aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/Makefile17
-rw-r--r--drivers/gpu/drm/i915/dvo.h157
-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.c338
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c42
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h93
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c628
-rw-r--r--drivers/gpu/drm/i915/i915_gem_proc.c34
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c1
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c51
-rw-r--r--drivers/gpu/drm/i915/i915_mem.c3
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c4
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h20
-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.c1618
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h146
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c495
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c925
-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.c1128
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo_regs.h327
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c1725
30 files changed, 11218 insertions, 109 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..e747ac42fe3a
--- /dev/null
+++ b/drivers/gpu/drm/i915/dvo.h
@@ -0,0 +1,157 @@
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
151extern struct intel_dvo_dev_ops sil164_ops;
152extern struct intel_dvo_dev_ops ch7xxx_ops;
153extern struct intel_dvo_dev_ops ivch_ops;
154extern struct intel_dvo_dev_ops tfp410_ops;
155extern struct intel_dvo_dev_ops ch7017_ops;
156
157#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 afa8a12cd009..3d7082af5b72 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
@@ -39,6 +41,7 @@
39int i915_wait_ring(struct drm_device * dev, int n, const char *caller) 41int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
40{ 42{
41 drm_i915_private_t *dev_priv = dev->dev_private; 43 drm_i915_private_t *dev_priv = dev->dev_private;
44 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
42 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 45 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
43 u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; 46 u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
44 u32 last_acthd = I915_READ(acthd_reg); 47 u32 last_acthd = I915_READ(acthd_reg);
@@ -55,8 +58,8 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
55 if (ring->space >= n) 58 if (ring->space >= n)
56 return 0; 59 return 0;
57 60
58 if (dev_priv->sarea_priv) 61 if (master_priv->sarea_priv)
59 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 62 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
60 63
61 if (ring->head != last_head) 64 if (ring->head != last_head)
62 i = 0; 65 i = 0;
@@ -121,16 +124,28 @@ static void i915_free_hws(struct drm_device *dev)
121void i915_kernel_lost_context(struct drm_device * dev) 124void i915_kernel_lost_context(struct drm_device * dev)
122{ 125{
123 drm_i915_private_t *dev_priv = dev->dev_private; 126 drm_i915_private_t *dev_priv = dev->dev_private;
127 struct drm_i915_master_private *master_priv;
124 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 128 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
125 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
126 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; 137 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
127 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; 138 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
128 ring->space = ring->head - (ring->tail + 8); 139 ring->space = ring->head - (ring->tail + 8);
129 if (ring->space < 0) 140 if (ring->space < 0)
130 ring->space += ring->Size; 141 ring->space += ring->Size;
131 142
132 if (ring->head == ring->tail && dev_priv->sarea_priv) 143 if (!dev->primary->master)
133 dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; 144 return;
145
146 master_priv = dev->primary->master->driver_priv;
147 if (ring->head == ring->tail && master_priv->sarea_priv)
148 master_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
134} 149}
135 150
136static int i915_dma_cleanup(struct drm_device * dev) 151static int i915_dma_cleanup(struct drm_device * dev)
@@ -154,25 +169,13 @@ static int i915_dma_cleanup(struct drm_device * dev)
154 if (I915_NEED_GFX_HWS(dev)) 169 if (I915_NEED_GFX_HWS(dev))
155 i915_free_hws(dev); 170 i915_free_hws(dev);
156 171
157 dev_priv->sarea = NULL;
158 dev_priv->sarea_priv = NULL;
159
160 return 0; 172 return 0;
161} 173}
162 174
163static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) 175static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
164{ 176{
165 drm_i915_private_t *dev_priv = dev->dev_private; 177 drm_i915_private_t *dev_priv = dev->dev_private;
166 178 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
167 dev_priv->sarea = drm_getsarea(dev);
168 if (!dev_priv->sarea) {
169 DRM_ERROR("can not find sarea!\n");
170 i915_dma_cleanup(dev);
171 return -EINVAL;
172 }
173
174 dev_priv->sarea_priv = (drm_i915_sarea_t *)
175 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
176 179
177 if (init->ring_size != 0) { 180 if (init->ring_size != 0) {
178 if (dev_priv->ring.ring_obj != NULL) { 181 if (dev_priv->ring.ring_obj != NULL) {
@@ -207,7 +210,8 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
207 dev_priv->back_offset = init->back_offset; 210 dev_priv->back_offset = init->back_offset;
208 dev_priv->front_offset = init->front_offset; 211 dev_priv->front_offset = init->front_offset;
209 dev_priv->current_page = 0; 212 dev_priv->current_page = 0;
210 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 213 if (master_priv->sarea_priv)
214 master_priv->sarea_priv->pf_current_page = 0;
211 215
212 /* Allow hardware batchbuffers unless told otherwise. 216 /* Allow hardware batchbuffers unless told otherwise.
213 */ 217 */
@@ -222,11 +226,6 @@ static int i915_dma_resume(struct drm_device * dev)
222 226
223 DRM_DEBUG("%s\n", __func__); 227 DRM_DEBUG("%s\n", __func__);
224 228
225 if (!dev_priv->sarea) {
226 DRM_ERROR("can not find sarea!\n");
227 return -EINVAL;
228 }
229
230 if (dev_priv->ring.map.handle == NULL) { 229 if (dev_priv->ring.map.handle == NULL) {
231 DRM_ERROR("can not ioremap virtual address for" 230 DRM_ERROR("can not ioremap virtual address for"
232 " ring buffer\n"); 231 " ring buffer\n");
@@ -435,13 +434,14 @@ i915_emit_box(struct drm_device *dev,
435static void i915_emit_breadcrumb(struct drm_device *dev) 434static void i915_emit_breadcrumb(struct drm_device *dev)
436{ 435{
437 drm_i915_private_t *dev_priv = dev->dev_private; 436 drm_i915_private_t *dev_priv = dev->dev_private;
437 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
438 RING_LOCALS; 438 RING_LOCALS;
439 439
440 dev_priv->counter++; 440 dev_priv->counter++;
441 if (dev_priv->counter > 0x7FFFFFFFUL) 441 if (dev_priv->counter > 0x7FFFFFFFUL)
442 dev_priv->counter = 0; 442 dev_priv->counter = 0;
443 if (dev_priv->sarea_priv) 443 if (master_priv->sarea_priv)
444 dev_priv->sarea_priv->last_enqueue = dev_priv->counter; 444 master_priv->sarea_priv->last_enqueue = dev_priv->counter;
445 445
446 BEGIN_LP_RING(4); 446 BEGIN_LP_RING(4);
447 OUT_RING(MI_STORE_DWORD_INDEX); 447 OUT_RING(MI_STORE_DWORD_INDEX);
@@ -537,15 +537,17 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
537static int i915_dispatch_flip(struct drm_device * dev) 537static int i915_dispatch_flip(struct drm_device * dev)
538{ 538{
539 drm_i915_private_t *dev_priv = dev->dev_private; 539 drm_i915_private_t *dev_priv = dev->dev_private;
540 struct drm_i915_master_private *master_priv =
541 dev->primary->master->driver_priv;
540 RING_LOCALS; 542 RING_LOCALS;
541 543
542 if (!dev_priv->sarea_priv) 544 if (!master_priv->sarea_priv)
543 return -EINVAL; 545 return -EINVAL;
544 546
545 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", 547 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
546 __func__, 548 __func__,
547 dev_priv->current_page, 549 dev_priv->current_page,
548 dev_priv->sarea_priv->pf_current_page); 550 master_priv->sarea_priv->pf_current_page);
549 551
550 i915_kernel_lost_context(dev); 552 i915_kernel_lost_context(dev);
551 553
@@ -572,7 +574,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
572 OUT_RING(0); 574 OUT_RING(0);
573 ADVANCE_LP_RING(); 575 ADVANCE_LP_RING();
574 576
575 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; 577 master_priv->sarea_priv->last_enqueue = dev_priv->counter++;
576 578
577 BEGIN_LP_RING(4); 579 BEGIN_LP_RING(4);
578 OUT_RING(MI_STORE_DWORD_INDEX); 580 OUT_RING(MI_STORE_DWORD_INDEX);
@@ -581,7 +583,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
581 OUT_RING(0); 583 OUT_RING(0);
582 ADVANCE_LP_RING(); 584 ADVANCE_LP_RING();
583 585
584 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 586 master_priv->sarea_priv->pf_current_page = dev_priv->current_page;
585 return 0; 587 return 0;
586} 588}
587 589
@@ -611,8 +613,9 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
611 struct drm_file *file_priv) 613 struct drm_file *file_priv)
612{ 614{
613 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 615 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
616 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
614 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 617 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
615 dev_priv->sarea_priv; 618 master_priv->sarea_priv;
616 drm_i915_batchbuffer_t *batch = data; 619 drm_i915_batchbuffer_t *batch = data;
617 int ret; 620 int ret;
618 621
@@ -644,8 +647,9 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
644 struct drm_file *file_priv) 647 struct drm_file *file_priv)
645{ 648{
646 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 649 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
650 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
647 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 651 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
648 dev_priv->sarea_priv; 652 master_priv->sarea_priv;
649 drm_i915_cmdbuffer_t *cmdbuf = data; 653 drm_i915_cmdbuffer_t *cmdbuf = data;
650 int ret; 654 int ret;
651 655
@@ -774,6 +778,11 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
774 return -EINVAL; 778 return -EINVAL;
775 } 779 }
776 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
777 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);
778 787
779 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); 788 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
@@ -802,6 +811,214 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
802 return 0; 811 return 0;
803} 812}
804 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 */
824static int i915_probe_agp(struct drm_device *dev, 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 (dev->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(dev->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 if (IS_G4X(dev))
865 overhead = 4096;
866 else
867 overhead = (*aperture_size / 1024) + 4096;
868
869 switch (tmp & INTEL_855_GMCH_GMS_MASK) {
870 case INTEL_855_GMCH_GMS_STOLEN_1M:
871 break; /* 1M already */
872 case INTEL_855_GMCH_GMS_STOLEN_4M:
873 *preallocated_size *= 4;
874 break;
875 case INTEL_855_GMCH_GMS_STOLEN_8M:
876 *preallocated_size *= 8;
877 break;
878 case INTEL_855_GMCH_GMS_STOLEN_16M:
879 *preallocated_size *= 16;
880 break;
881 case INTEL_855_GMCH_GMS_STOLEN_32M:
882 *preallocated_size *= 32;
883 break;
884 case INTEL_915G_GMCH_GMS_STOLEN_48M:
885 *preallocated_size *= 48;
886 break;
887 case INTEL_915G_GMCH_GMS_STOLEN_64M:
888 *preallocated_size *= 64;
889 break;
890 case INTEL_855_GMCH_GMS_DISABLED:
891 DRM_ERROR("video memory is disabled\n");
892 return -1;
893 default:
894 DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n",
895 tmp & INTEL_855_GMCH_GMS_MASK);
896 return -1;
897 }
898 *preallocated_size -= overhead;
899
900 return 0;
901}
902
903static int i915_load_modeset_init(struct drm_device *dev)
904{
905 struct drm_i915_private *dev_priv = dev->dev_private;
906 unsigned long agp_size, prealloc_size;
907 int fb_bar = IS_I9XX(dev) ? 2 : 0;
908 int ret = 0;
909
910 dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL);
911 if (!dev->devname) {
912 ret = -ENOMEM;
913 goto out;
914 }
915
916 dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
917 0xff000000;
918
919 DRM_DEBUG("*** fb base 0x%08lx\n", dev->mode_config.fb_base);
920
921 if (IS_MOBILE(dev) || (IS_I9XX(dev) && !IS_I965G(dev) && !IS_G33(dev)))
922 dev_priv->cursor_needs_physical = true;
923 else
924 dev_priv->cursor_needs_physical = false;
925
926 ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
927 if (ret)
928 goto kfree_devname;
929
930 /* Basic memrange allocator for stolen space (aka vram) */
931 drm_mm_init(&dev_priv->vram, 0, prealloc_size);
932
933 /* Let GEM Manage from end of prealloc space to end of aperture */
934 i915_gem_do_init(dev, prealloc_size, agp_size);
935
936 ret = i915_gem_init_ringbuffer(dev);
937 if (ret)
938 goto kfree_devname;
939
940 dev_priv->mm.gtt_mapping =
941 io_mapping_create_wc(dev->agp->base,
942 dev->agp->agp_info.aper_size * 1024*1024);
943
944 /* Allow hardware batchbuffers unless told otherwise.
945 */
946 dev_priv->allow_batchbuffer = 1;
947
948 ret = intel_init_bios(dev);
949 if (ret)
950 DRM_INFO("failed to find VBIOS tables\n");
951
952 ret = drm_irq_install(dev);
953 if (ret)
954 goto destroy_ringbuffer;
955
956 /* FIXME: re-add hotplug support */
957#if 0
958 ret = drm_hotplug_init(dev);
959 if (ret)
960 goto destroy_ringbuffer;
961#endif
962
963 /* Always safe in the mode setting case. */
964 /* FIXME: do pre/post-mode set stuff in core KMS code */
965 dev->vblank_disable_allowed = 1;
966
967 /*
968 * Initialize the hardware status page IRQ location.
969 */
970
971 I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
972
973 intel_modeset_init(dev);
974
975 drm_helper_initial_config(dev, false);
976
977 return 0;
978
979destroy_ringbuffer:
980 i915_gem_cleanup_ringbuffer(dev);
981kfree_devname:
982 kfree(dev->devname);
983out:
984 return ret;
985}
986
987int i915_master_create(struct drm_device *dev, struct drm_master *master)
988{
989 struct drm_i915_master_private *master_priv;
990
991 master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER);
992 if (!master_priv)
993 return -ENOMEM;
994
995 master->driver_priv = master_priv;
996 return 0;
997}
998
999void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
1000{
1001 struct drm_i915_master_private *master_priv = master->driver_priv;
1002
1003 if (!master_priv)
1004 return;
1005
1006 drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER);
1007
1008 master->driver_priv = NULL;
1009}
1010
1011/**
1012 * i915_driver_load - setup chip and create an initial config
1013 * @dev: DRM device
1014 * @flags: startup flags
1015 *
1016 * The driver load routine has to do several things:
1017 * - drive output discovery via intel_modeset_init()
1018 * - initialize the memory manager
1019 * - allocate initial config memory
1020 * - setup the DRM framebuffer with the allocated memory
1021 */
805int i915_driver_load(struct drm_device *dev, unsigned long flags) 1022int i915_driver_load(struct drm_device *dev, unsigned long flags)
806{ 1023{
807 struct drm_i915_private *dev_priv = dev->dev_private; 1024 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -829,6 +1046,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
829 size = drm_get_resource_len(dev, mmio_bar); 1046 size = drm_get_resource_len(dev, mmio_bar);
830 1047
831 dev_priv->regs = ioremap(base, size); 1048 dev_priv->regs = ioremap(base, size);
1049 if (!dev_priv->regs) {
1050 DRM_ERROR("failed to map registers\n");
1051 ret = -EIO;
1052 goto free_priv;
1053 }
832 1054
833#ifdef CONFIG_HIGHMEM64G 1055#ifdef CONFIG_HIGHMEM64G
834 /* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */ 1056 /* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */
@@ -844,7 +1066,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
844 if (!I915_NEED_GFX_HWS(dev)) { 1066 if (!I915_NEED_GFX_HWS(dev)) {
845 ret = i915_init_phys_hws(dev); 1067 ret = i915_init_phys_hws(dev);
846 if (ret != 0) 1068 if (ret != 0)
847 return ret; 1069 goto out_rmmap;
848 } 1070 }
849 1071
850 /* On the 945G/GM, the chipset reports the MSI capability on the 1072 /* On the 945G/GM, the chipset reports the MSI capability on the
@@ -864,6 +1086,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
864 intel_opregion_init(dev); 1086 intel_opregion_init(dev);
865 1087
866 spin_lock_init(&dev_priv->user_irq_lock); 1088 spin_lock_init(&dev_priv->user_irq_lock);
1089 dev_priv->user_irq_refcount = 0;
867 1090
868 ret = drm_vblank_init(dev, I915_NUM_PIPE); 1091 ret = drm_vblank_init(dev, I915_NUM_PIPE);
869 1092
@@ -872,6 +1095,20 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
872 return ret; 1095 return ret;
873 } 1096 }
874 1097
1098 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1099 ret = i915_load_modeset_init(dev);
1100 if (ret < 0) {
1101 DRM_ERROR("failed to init modeset\n");
1102 goto out_rmmap;
1103 }
1104 }
1105
1106 return 0;
1107
1108out_rmmap:
1109 iounmap(dev_priv->regs);
1110free_priv:
1111 drm_free(dev_priv, sizeof(struct drm_i915_private), DRM_MEM_DRIVER);
875 return ret; 1112 return ret;
876} 1113}
877 1114
@@ -879,16 +1116,29 @@ int i915_driver_unload(struct drm_device *dev)
879{ 1116{
880 struct drm_i915_private *dev_priv = dev->dev_private; 1117 struct drm_i915_private *dev_priv = dev->dev_private;
881 1118
1119 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1120 io_mapping_free(dev_priv->mm.gtt_mapping);
1121 drm_irq_uninstall(dev);
1122 }
1123
882 if (dev->pdev->msi_enabled) 1124 if (dev->pdev->msi_enabled)
883 pci_disable_msi(dev->pdev); 1125 pci_disable_msi(dev->pdev);
884 1126
885 i915_free_hws(dev);
886
887 if (dev_priv->regs != NULL) 1127 if (dev_priv->regs != NULL)
888 iounmap(dev_priv->regs); 1128 iounmap(dev_priv->regs);
889 1129
890 intel_opregion_free(dev); 1130 intel_opregion_free(dev);
891 1131
1132 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1133 intel_modeset_cleanup(dev);
1134
1135 mutex_lock(&dev->struct_mutex);
1136 i915_gem_cleanup_ringbuffer(dev);
1137 mutex_unlock(&dev->struct_mutex);
1138 drm_mm_takedown(&dev_priv->vram);
1139 i915_gem_lastclose(dev);
1140 }
1141
892 drm_free(dev->dev_private, sizeof(drm_i915_private_t), 1142 drm_free(dev->dev_private, sizeof(drm_i915_private_t),
893 DRM_MEM_DRIVER); 1143 DRM_MEM_DRIVER);
894 1144
@@ -914,12 +1164,26 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
914 return 0; 1164 return 0;
915} 1165}
916 1166
1167/**
1168 * i915_driver_lastclose - clean up after all DRM clients have exited
1169 * @dev: DRM device
1170 *
1171 * Take care of cleaning up after all DRM clients have exited. In the
1172 * mode setting case, we want to restore the kernel's initial mode (just
1173 * in case the last client left us in a bad state).
1174 *
1175 * Additionally, in the non-mode setting case, we'll tear down the AGP
1176 * and DMA structures, since the kernel won't be using them, and clea
1177 * up any GEM state.
1178 */
917void i915_driver_lastclose(struct drm_device * dev) 1179void i915_driver_lastclose(struct drm_device * dev)
918{ 1180{
919 drm_i915_private_t *dev_priv = dev->dev_private; 1181 drm_i915_private_t *dev_priv = dev->dev_private;
920 1182
921 if (!dev_priv) 1183 if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) {
1184 intelfb_restore();
922 return; 1185 return;
1186 }
923 1187
924 i915_gem_lastclose(dev); 1188 i915_gem_lastclose(dev);
925 1189
@@ -932,7 +1196,8 @@ void i915_driver_lastclose(struct drm_device * dev)
932void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) 1196void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
933{ 1197{
934 drm_i915_private_t *dev_priv = dev->dev_private; 1198 drm_i915_private_t *dev_priv = dev->dev_private;
935 i915_mem_release(dev, file_priv, dev_priv->agp_heap); 1199 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1200 i915_mem_release(dev, file_priv, dev_priv->agp_heap);
936} 1201}
937 1202
938void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) 1203void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
@@ -972,6 +1237,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
972 DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0), 1237 DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
973 DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0), 1238 DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
974 DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0), 1239 DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
1240 DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 0),
975 DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0), 1241 DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
976 DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0), 1242 DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
977 DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0), 1243 DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a80ead215282..f8b3df0926c0 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
38static unsigned 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;
@@ -81,6 +92,10 @@ static int i915_resume(struct drm_device *dev)
81 return 0; 92 return 0;
82} 93}
83 94
95static struct vm_operations_struct i915_gem_vm_ops = {
96 .fault = i915_gem_fault,
97};
98
84static struct drm_driver driver = { 99static struct drm_driver driver = {
85 /* don't use mtrr's here, the Xserver or user space app should 100 /* don't use mtrr's here, the Xserver or user space app should
86 * deal with them for intel hardware. 101 * deal with them for intel hardware.
@@ -107,17 +122,20 @@ static struct drm_driver driver = {
107 .reclaim_buffers = drm_core_reclaim_buffers, 122 .reclaim_buffers = drm_core_reclaim_buffers,
108 .get_map_ofs = drm_core_get_map_ofs, 123 .get_map_ofs = drm_core_get_map_ofs,
109 .get_reg_ofs = drm_core_get_reg_ofs, 124 .get_reg_ofs = drm_core_get_reg_ofs,
125 .master_create = i915_master_create,
126 .master_destroy = i915_master_destroy,
110 .proc_init = i915_gem_proc_init, 127 .proc_init = i915_gem_proc_init,
111 .proc_cleanup = i915_gem_proc_cleanup, 128 .proc_cleanup = i915_gem_proc_cleanup,
112 .gem_init_object = i915_gem_init_object, 129 .gem_init_object = i915_gem_init_object,
113 .gem_free_object = i915_gem_free_object, 130 .gem_free_object = i915_gem_free_object,
131 .gem_vm_ops = &i915_gem_vm_ops,
114 .ioctls = i915_ioctls, 132 .ioctls = i915_ioctls,
115 .fops = { 133 .fops = {
116 .owner = THIS_MODULE, 134 .owner = THIS_MODULE,
117 .open = drm_open, 135 .open = drm_open,
118 .release = drm_release, 136 .release = drm_release,
119 .ioctl = drm_ioctl, 137 .ioctl = drm_ioctl,
120 .mmap = drm_mmap, 138 .mmap = drm_gem_mmap,
121 .poll = drm_poll, 139 .poll = drm_poll,
122 .fasync = drm_fasync, 140 .fasync = drm_fasync,
123#ifdef CONFIG_COMPAT 141#ifdef CONFIG_COMPAT
@@ -141,6 +159,28 @@ static struct drm_driver driver = {
141static int __init i915_init(void) 159static int __init i915_init(void)
142{ 160{
143 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
144 return drm_init(&driver); 184 return drm_init(&driver);
145} 185}
146 186
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b3cc4731aa7c..4756e5cd6b5e 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:
@@ -103,15 +104,23 @@ struct intel_opregion {
103 int enabled; 104 int enabled;
104}; 105};
105 106
107struct drm_i915_master_private {
108 drm_local_map_t *sarea;
109 struct _drm_i915_sarea *sarea_priv;
110};
111#define I915_FENCE_REG_NONE -1
112
113struct drm_i915_fence_reg {
114 struct drm_gem_object *obj;
115};
116
106typedef struct drm_i915_private { 117typedef struct drm_i915_private {
107 struct drm_device *dev; 118 struct drm_device *dev;
108 119
109 int has_gem; 120 int has_gem;
110 121
111 void __iomem *regs; 122 void __iomem *regs;
112 drm_local_map_t *sarea;
113 123
114 drm_i915_sarea_t *sarea_priv;
115 drm_i915_ring_buffer_t ring; 124 drm_i915_ring_buffer_t ring;
116 125
117 drm_dma_handle_t *status_page_dmah; 126 drm_dma_handle_t *status_page_dmah;
@@ -144,8 +153,30 @@ typedef struct drm_i915_private {
144 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; 153 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
145 int vblank_pipe; 154 int vblank_pipe;
146 155
156 bool cursor_needs_physical;
157
158 struct drm_mm vram;
159
160 int irq_enabled;
161
147 struct intel_opregion opregion; 162 struct intel_opregion opregion;
148 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 unsigned int int_tv_support:1;
172 unsigned int lvds_dither:1;
173 unsigned int lvds_vbt:1;
174 unsigned int int_crt_support:1;
175
176 struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
177 int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
178 int num_fence_regs; /* 8 on pre-965, 16 otherwise */
179
149 /* Register state */ 180 /* Register state */
150 u8 saveLBB; 181 u8 saveLBB;
151 u32 saveDSPACNTR; 182 u32 saveDSPACNTR;
@@ -364,6 +395,21 @@ struct drm_i915_gem_object {
364 * This is the same as gtt_space->start 395 * This is the same as gtt_space->start
365 */ 396 */
366 uint32_t gtt_offset; 397 uint32_t gtt_offset;
398 /**
399 * Required alignment for the object
400 */
401 uint32_t gtt_alignment;
402 /**
403 * Fake offset for use by mmap(2)
404 */
405 uint64_t mmap_offset;
406
407 /**
408 * Fence register bits (if any) for this object. Will be set
409 * as needed when mapped into the GTT.
410 * Protected by dev->struct_mutex.
411 */
412 int fence_reg;
367 413
368 /** Boolean whether this object has a valid gtt offset. */ 414 /** Boolean whether this object has a valid gtt offset. */
369 int gtt_bound; 415 int gtt_bound;
@@ -376,6 +422,7 @@ struct drm_i915_gem_object {
376 422
377 /** Current tiling mode for the object. */ 423 /** Current tiling mode for the object. */
378 uint32_t tiling_mode; 424 uint32_t tiling_mode;
425 uint32_t stride;
379 426
380 /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */ 427 /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */
381 uint32_t agp_type; 428 uint32_t agp_type;
@@ -385,6 +432,10 @@ struct drm_i915_gem_object {
385 * flags which individual pages are valid. 432 * flags which individual pages are valid.
386 */ 433 */
387 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;
388}; 439};
389 440
390/** 441/**
@@ -414,8 +465,19 @@ struct drm_i915_file_private {
414 } mm; 465 } mm;
415}; 466};
416 467
468enum intel_chip_family {
469 CHIP_I8XX = 0x01,
470 CHIP_I9XX = 0x02,
471 CHIP_I915 = 0x04,
472 CHIP_I965 = 0x08,
473};
474
417extern struct drm_ioctl_desc i915_ioctls[]; 475extern struct drm_ioctl_desc i915_ioctls[];
418extern int i915_max_ioctl; 476extern int i915_max_ioctl;
477extern unsigned int i915_fbpercrtc;
478
479extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
480extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
419 481
420 /* i915_dma.c */ 482 /* i915_dma.c */
421extern void i915_kernel_lost_context(struct drm_device * dev); 483extern void i915_kernel_lost_context(struct drm_device * dev);
@@ -441,6 +503,7 @@ extern int i915_irq_wait(struct drm_device *dev, void *data,
441 struct drm_file *file_priv); 503 struct drm_file *file_priv);
442void i915_user_irq_get(struct drm_device *dev); 504void i915_user_irq_get(struct drm_device *dev);
443void 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);
444 507
445extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); 508extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
446extern void i915_driver_irq_preinstall(struct drm_device * dev); 509extern void i915_driver_irq_preinstall(struct drm_device * dev);
@@ -487,6 +550,8 @@ int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
487 struct drm_file *file_priv); 550 struct drm_file *file_priv);
488int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, 551int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
489 struct drm_file *file_priv); 552 struct drm_file *file_priv);
553int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
554 struct drm_file *file_priv);
490int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, 555int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
491 struct drm_file *file_priv); 556 struct drm_file *file_priv);
492int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, 557int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
@@ -523,6 +588,16 @@ uint32_t i915_get_gem_seqno(struct drm_device *dev);
523void i915_gem_retire_requests(struct drm_device *dev); 588void i915_gem_retire_requests(struct drm_device *dev);
524void i915_gem_retire_work_handler(struct work_struct *work); 589void i915_gem_retire_work_handler(struct work_struct *work);
525void 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);
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);
526 601
527/* i915_gem_tiling.c */ 602/* i915_gem_tiling.c */
528void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); 603void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
@@ -561,6 +636,10 @@ static inline void opregion_asle_intr(struct drm_device *dev) { return; }
561static inline void opregion_enable_asle(struct drm_device *dev) { return; } 636static inline void opregion_enable_asle(struct drm_device *dev) { return; }
562#endif 637#endif
563 638
639/* modesetting */
640extern void intel_modeset_init(struct drm_device *dev);
641extern void intel_modeset_cleanup(struct drm_device *dev);
642
564/** 643/**
565 * 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.
566 * 645 *
@@ -578,6 +657,13 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; }
578#define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg)) 657#define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg))
579#define I915_READ8(reg) readb(dev_priv->regs + (reg)) 658#define I915_READ8(reg) readb(dev_priv->regs + (reg))
580#define I915_WRITE8(reg, val) writeb(val, dev_priv->regs + (reg)) 659#define I915_WRITE8(reg, val) writeb(val, dev_priv->regs + (reg))
660#ifdef writeq
661#define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg))
662#else
663#define I915_WRITE64(reg, val) (writel(val, dev_priv->regs + (reg)), \
664 writel(upper_32_bits(val), dev_priv->regs + \
665 (reg) + 4))
666#endif
581 667
582#define I915_VERBOSE 0 668#define I915_VERBOSE 0
583 669
@@ -660,7 +746,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
660 746
661#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \ 747#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \
662 (dev)->pci_device == 0x2E12 || \ 748 (dev)->pci_device == 0x2E12 || \
663 (dev)->pci_device == 0x2E22) 749 (dev)->pci_device == 0x2E22 || \
750 IS_GM45(dev))
664 751
665#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ 752#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
666 (dev)->pci_device == 0x29B2 || \ 753 (dev)->pci_device == 0x29B2 || \
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 24fe8c10b4b2..cc2ca5561feb 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,
@@ -51,34 +50,43 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o
51static int i915_gem_object_get_page_list(struct drm_gem_object *obj); 50static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
52static void i915_gem_object_free_page_list(struct drm_gem_object *obj); 51static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
53static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); 52static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
53static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
54 unsigned alignment);
55static void i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
56static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
57static int i915_gem_evict_something(struct drm_device *dev);
58
59int i915_gem_do_init(struct drm_device *dev, unsigned long start,
60 unsigned long end)
61{
62 drm_i915_private_t *dev_priv = dev->dev_private;
54 63
55static void 64 if (start >= end ||
56i915_gem_cleanup_ringbuffer(struct drm_device *dev); 65 (start & (PAGE_SIZE - 1)) != 0 ||
66 (end & (PAGE_SIZE - 1)) != 0) {
67 return -EINVAL;
68 }
69
70 drm_mm_init(&dev_priv->mm.gtt_space, start,
71 end - start);
72
73 dev->gtt_total = (uint32_t) (end - start);
74
75 return 0;
76}
57 77
58int 78int
59i915_gem_init_ioctl(struct drm_device *dev, void *data, 79i915_gem_init_ioctl(struct drm_device *dev, void *data,
60 struct drm_file *file_priv) 80 struct drm_file *file_priv)
61{ 81{
62 drm_i915_private_t *dev_priv = dev->dev_private;
63 struct drm_i915_gem_init *args = data; 82 struct drm_i915_gem_init *args = data;
83 int ret;
64 84
65 mutex_lock(&dev->struct_mutex); 85 mutex_lock(&dev->struct_mutex);
66 86 ret = i915_gem_do_init(dev, args->gtt_start, args->gtt_end);
67 if (args->gtt_start >= args->gtt_end ||
68 (args->gtt_start & (PAGE_SIZE - 1)) != 0 ||
69 (args->gtt_end & (PAGE_SIZE - 1)) != 0) {
70 mutex_unlock(&dev->struct_mutex);
71 return -EINVAL;
72 }
73
74 drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start,
75 args->gtt_end - args->gtt_start);
76
77 dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start);
78
79 mutex_unlock(&dev->struct_mutex); 87 mutex_unlock(&dev->struct_mutex);
80 88
81 return 0; 89 return ret;
82} 90}
83 91
84int 92int
@@ -529,6 +537,252 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
529 return 0; 537 return 0;
530} 538}
531 539
540/**
541 * i915_gem_fault - fault a page into the GTT
542 * vma: VMA in question
543 * vmf: fault info
544 *
545 * The fault handler is set up by drm_gem_mmap() when a object is GTT mapped
546 * from userspace. The fault handler takes care of binding the object to
547 * the GTT (if needed), allocating and programming a fence register (again,
548 * only if needed based on whether the old reg is still valid or the object
549 * is tiled) and inserting a new PTE into the faulting process.
550 *
551 * Note that the faulting process may involve evicting existing objects
552 * from the GTT and/or fence registers to make room. So performance may
553 * suffer if the GTT working set is large or there are few fence registers
554 * left.
555 */
556int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
557{
558 struct drm_gem_object *obj = vma->vm_private_data;
559 struct drm_device *dev = obj->dev;
560 struct drm_i915_private *dev_priv = dev->dev_private;
561 struct drm_i915_gem_object *obj_priv = obj->driver_private;
562 pgoff_t page_offset;
563 unsigned long pfn;
564 int ret = 0;
565
566 /* We don't use vmf->pgoff since that has the fake offset */
567 page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >>
568 PAGE_SHIFT;
569
570 /* Now bind it into the GTT if needed */
571 mutex_lock(&dev->struct_mutex);
572 if (!obj_priv->gtt_space) {
573 ret = i915_gem_object_bind_to_gtt(obj, obj_priv->gtt_alignment);
574 if (ret) {
575 mutex_unlock(&dev->struct_mutex);
576 return VM_FAULT_SIGBUS;
577 }
578 list_add(&obj_priv->list, &dev_priv->mm.inactive_list);
579 }
580
581 /* Need a new fence register? */
582 if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
583 obj_priv->tiling_mode != I915_TILING_NONE)
584 i915_gem_object_get_fence_reg(obj);
585
586 pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) +
587 page_offset;
588
589 /* Finally, remap it using the new GTT offset */
590 ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
591
592 mutex_unlock(&dev->struct_mutex);
593
594 switch (ret) {
595 case -ENOMEM:
596 case -EAGAIN:
597 return VM_FAULT_OOM;
598 case -EFAULT:
599 case -EBUSY:
600 DRM_ERROR("can't insert pfn?? fault or busy...\n");
601 return VM_FAULT_SIGBUS;
602 default:
603 return VM_FAULT_NOPAGE;
604 }
605}
606
607/**
608 * i915_gem_create_mmap_offset - create a fake mmap offset for an object
609 * @obj: obj in question
610 *
611 * GEM memory mapping works by handing back to userspace a fake mmap offset
612 * it can use in a subsequent mmap(2) call. The DRM core code then looks
613 * up the object based on the offset and sets up the various memory mapping
614 * structures.
615 *
616 * This routine allocates and attaches a fake offset for @obj.
617 */
618static int
619i915_gem_create_mmap_offset(struct drm_gem_object *obj)
620{
621 struct drm_device *dev = obj->dev;
622 struct drm_gem_mm *mm = dev->mm_private;
623 struct drm_i915_gem_object *obj_priv = obj->driver_private;
624 struct drm_map_list *list;
625 struct drm_map *map;
626 int ret = 0;
627
628 /* Set the object up for mmap'ing */
629 list = &obj->map_list;
630 list->map = drm_calloc(1, sizeof(struct drm_map_list),
631 DRM_MEM_DRIVER);
632 if (!list->map)
633 return -ENOMEM;
634
635 map = list->map;
636 map->type = _DRM_GEM;
637 map->size = obj->size;
638 map->handle = obj;
639
640 /* Get a DRM GEM mmap offset allocated... */
641 list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
642 obj->size / PAGE_SIZE, 0, 0);
643 if (!list->file_offset_node) {
644 DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
645 ret = -ENOMEM;
646 goto out_free_list;
647 }
648
649 list->file_offset_node = drm_mm_get_block(list->file_offset_node,
650 obj->size / PAGE_SIZE, 0);
651 if (!list->file_offset_node) {
652 ret = -ENOMEM;
653 goto out_free_list;
654 }
655
656 list->hash.key = list->file_offset_node->start;
657 if (drm_ht_insert_item(&mm->offset_hash, &list->hash)) {
658 DRM_ERROR("failed to add to map hash\n");
659 goto out_free_mm;
660 }
661
662 /* By now we should be all set, any drm_mmap request on the offset
663 * below will get to our mmap & fault handler */
664 obj_priv->mmap_offset = ((uint64_t) list->hash.key) << PAGE_SHIFT;
665
666 return 0;
667
668out_free_mm:
669 drm_mm_put_block(list->file_offset_node);
670out_free_list:
671 drm_free(list->map, sizeof(struct drm_map_list), DRM_MEM_DRIVER);
672
673 return ret;
674}
675
676/**
677 * i915_gem_get_gtt_alignment - return required GTT alignment for an object
678 * @obj: object to check
679 *
680 * Return the required GTT alignment for an object, taking into account
681 * potential fence register mapping if needed.
682 */
683static uint32_t
684i915_gem_get_gtt_alignment(struct drm_gem_object *obj)
685{
686 struct drm_device *dev = obj->dev;
687 struct drm_i915_gem_object *obj_priv = obj->driver_private;
688 int start, i;
689
690 /*
691 * Minimum alignment is 4k (GTT page size), but might be greater
692 * if a fence register is needed for the object.
693 */
694 if (IS_I965G(dev) || obj_priv->tiling_mode == I915_TILING_NONE)
695 return 4096;
696
697 /*
698 * Previous chips need to be aligned to the size of the smallest
699 * fence register that can contain the object.
700 */
701 if (IS_I9XX(dev))
702 start = 1024*1024;
703 else
704 start = 512*1024;
705
706 for (i = start; i < obj->size; i <<= 1)
707 ;
708
709 return i;
710}
711
712/**
713 * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
714 * @dev: DRM device
715 * @data: GTT mapping ioctl data
716 * @file_priv: GEM object info
717 *
718 * Simply returns the fake offset to userspace so it can mmap it.
719 * The mmap call will end up in drm_gem_mmap(), which will set things
720 * up so we can get faults in the handler above.
721 *
722 * The fault handler will take care of binding the object into the GTT
723 * (since it may have been evicted to make room for something), allocating
724 * a fence register, and mapping the appropriate aperture address into
725 * userspace.
726 */
727int
728i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
729 struct drm_file *file_priv)
730{
731 struct drm_i915_gem_mmap_gtt *args = data;
732 struct drm_i915_private *dev_priv = dev->dev_private;
733 struct drm_gem_object *obj;
734 struct drm_i915_gem_object *obj_priv;
735 int ret;
736
737 if (!(dev->driver->driver_features & DRIVER_GEM))
738 return -ENODEV;
739
740 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
741 if (obj == NULL)
742 return -EBADF;
743
744 mutex_lock(&dev->struct_mutex);
745
746 obj_priv = obj->driver_private;
747
748 if (!obj_priv->mmap_offset) {
749 ret = i915_gem_create_mmap_offset(obj);
750 if (ret)
751 return ret;
752 }
753
754 args->offset = obj_priv->mmap_offset;
755
756 obj_priv->gtt_alignment = i915_gem_get_gtt_alignment(obj);
757
758 /* Make sure the alignment is correct for fence regs etc */
759 if (obj_priv->agp_mem &&
760 (obj_priv->gtt_offset & (obj_priv->gtt_alignment - 1))) {
761 drm_gem_object_unreference(obj);
762 mutex_unlock(&dev->struct_mutex);
763 return -EINVAL;
764 }
765
766 /*
767 * Pull it into the GTT so that we have a page list (makes the
768 * initial fault faster and any subsequent flushing possible).
769 */
770 if (!obj_priv->agp_mem) {
771 ret = i915_gem_object_bind_to_gtt(obj, obj_priv->gtt_alignment);
772 if (ret) {
773 drm_gem_object_unreference(obj);
774 mutex_unlock(&dev->struct_mutex);
775 return ret;
776 }
777 list_add(&obj_priv->list, &dev_priv->mm.inactive_list);
778 }
779
780 drm_gem_object_unreference(obj);
781 mutex_unlock(&dev->struct_mutex);
782
783 return 0;
784}
785
532static void 786static void
533i915_gem_object_free_page_list(struct drm_gem_object *obj) 787i915_gem_object_free_page_list(struct drm_gem_object *obj)
534{ 788{
@@ -726,6 +980,7 @@ i915_gem_retire_request(struct drm_device *dev,
726 */ 980 */
727 if (obj_priv->last_rendering_seqno != request->seqno) 981 if (obj_priv->last_rendering_seqno != request->seqno)
728 return; 982 return;
983
729#if WATCH_LRU 984#if WATCH_LRU
730 DRM_INFO("%s: retire %d moves to inactive list %p\n", 985 DRM_INFO("%s: retire %d moves to inactive list %p\n",
731 __func__, request->seqno, obj); 986 __func__, request->seqno, obj);
@@ -956,6 +1211,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
956{ 1211{
957 struct drm_device *dev = obj->dev; 1212 struct drm_device *dev = obj->dev;
958 struct drm_i915_gem_object *obj_priv = obj->driver_private; 1213 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1214 loff_t offset;
959 int ret = 0; 1215 int ret = 0;
960 1216
961#if WATCH_BUF 1217#if WATCH_BUF
@@ -991,6 +1247,14 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
991 1247
992 BUG_ON(obj_priv->active); 1248 BUG_ON(obj_priv->active);
993 1249
1250 /* blow away mappings if mapped through GTT */
1251 offset = ((loff_t) obj->map_list.hash.key) << PAGE_SHIFT;
1252 if (dev->dev_mapping)
1253 unmap_mapping_range(dev->dev_mapping, offset, obj->size, 1);
1254
1255 if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
1256 i915_gem_clear_fence_reg(obj);
1257
994 i915_gem_object_free_page_list(obj); 1258 i915_gem_object_free_page_list(obj);
995 1259
996 if (obj_priv->gtt_space) { 1260 if (obj_priv->gtt_space) {
@@ -1149,6 +1413,204 @@ i915_gem_object_get_page_list(struct drm_gem_object *obj)
1149 return 0; 1413 return 0;
1150} 1414}
1151 1415
1416static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
1417{
1418 struct drm_gem_object *obj = reg->obj;
1419 struct drm_device *dev = obj->dev;
1420 drm_i915_private_t *dev_priv = dev->dev_private;
1421 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1422 int regnum = obj_priv->fence_reg;
1423 uint64_t val;
1424
1425 val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) &
1426 0xfffff000) << 32;
1427 val |= obj_priv->gtt_offset & 0xfffff000;
1428 val |= ((obj_priv->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT;
1429 if (obj_priv->tiling_mode == I915_TILING_Y)
1430 val |= 1 << I965_FENCE_TILING_Y_SHIFT;
1431 val |= I965_FENCE_REG_VALID;
1432
1433 I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val);
1434}
1435
1436static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
1437{
1438 struct drm_gem_object *obj = reg->obj;
1439 struct drm_device *dev = obj->dev;
1440 drm_i915_private_t *dev_priv = dev->dev_private;
1441 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1442 int regnum = obj_priv->fence_reg;
1443 uint32_t val;
1444 uint32_t pitch_val;
1445
1446 if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
1447 (obj_priv->gtt_offset & (obj->size - 1))) {
1448 WARN(1, "%s: object not 1M or size aligned\n", __FUNCTION__);
1449 return;
1450 }
1451
1452 if (obj_priv->tiling_mode == I915_TILING_Y && (IS_I945G(dev) ||
1453 IS_I945GM(dev) ||
1454 IS_G33(dev)))
1455 pitch_val = (obj_priv->stride / 128) - 1;
1456 else
1457 pitch_val = (obj_priv->stride / 512) - 1;
1458
1459 val = obj_priv->gtt_offset;
1460 if (obj_priv->tiling_mode == I915_TILING_Y)
1461 val |= 1 << I830_FENCE_TILING_Y_SHIFT;
1462 val |= I915_FENCE_SIZE_BITS(obj->size);
1463 val |= pitch_val << I830_FENCE_PITCH_SHIFT;
1464 val |= I830_FENCE_REG_VALID;
1465
1466 I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val);
1467}
1468
1469static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
1470{
1471 struct drm_gem_object *obj = reg->obj;
1472 struct drm_device *dev = obj->dev;
1473 drm_i915_private_t *dev_priv = dev->dev_private;
1474 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1475 int regnum = obj_priv->fence_reg;
1476 uint32_t val;
1477 uint32_t pitch_val;
1478
1479 if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
1480 (obj_priv->gtt_offset & (obj->size - 1))) {
1481 WARN(1, "%s: object not 1M or size aligned\n", __FUNCTION__);
1482 return;
1483 }
1484
1485 pitch_val = (obj_priv->stride / 128) - 1;
1486
1487 val = obj_priv->gtt_offset;
1488 if (obj_priv->tiling_mode == I915_TILING_Y)
1489 val |= 1 << I830_FENCE_TILING_Y_SHIFT;
1490 val |= I830_FENCE_SIZE_BITS(obj->size);
1491 val |= pitch_val << I830_FENCE_PITCH_SHIFT;
1492 val |= I830_FENCE_REG_VALID;
1493
1494 I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val);
1495
1496}
1497
1498/**
1499 * i915_gem_object_get_fence_reg - set up a fence reg for an object
1500 * @obj: object to map through a fence reg
1501 *
1502 * When mapping objects through the GTT, userspace wants to be able to write
1503 * to them without having to worry about swizzling if the object is tiled.
1504 *
1505 * This function walks the fence regs looking for a free one for @obj,
1506 * stealing one if it can't find any.
1507 *
1508 * It then sets up the reg based on the object's properties: address, pitch
1509 * and tiling format.
1510 */
1511static void
1512i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
1513{
1514 struct drm_device *dev = obj->dev;
1515 struct drm_i915_private *dev_priv = dev->dev_private;
1516 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1517 struct drm_i915_fence_reg *reg = NULL;
1518 int i, ret;
1519
1520 switch (obj_priv->tiling_mode) {
1521 case I915_TILING_NONE:
1522 WARN(1, "allocating a fence for non-tiled object?\n");
1523 break;
1524 case I915_TILING_X:
1525 WARN(obj_priv->stride & (512 - 1),
1526 "object is X tiled but has non-512B pitch\n");
1527 break;
1528 case I915_TILING_Y:
1529 WARN(obj_priv->stride & (128 - 1),
1530 "object is Y tiled but has non-128B pitch\n");
1531 break;
1532 }
1533
1534 /* First try to find a free reg */
1535 for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
1536 reg = &dev_priv->fence_regs[i];
1537 if (!reg->obj)
1538 break;
1539 }
1540
1541 /* None available, try to steal one or wait for a user to finish */
1542 if (i == dev_priv->num_fence_regs) {
1543 struct drm_i915_gem_object *old_obj_priv = NULL;
1544 loff_t offset;
1545
1546try_again:
1547 /* Could try to use LRU here instead... */
1548 for (i = dev_priv->fence_reg_start;
1549 i < dev_priv->num_fence_regs; i++) {
1550 reg = &dev_priv->fence_regs[i];
1551 old_obj_priv = reg->obj->driver_private;
1552 if (!old_obj_priv->pin_count)
1553 break;
1554 }
1555
1556 /*
1557 * Now things get ugly... we have to wait for one of the
1558 * objects to finish before trying again.
1559 */
1560 if (i == dev_priv->num_fence_regs) {
1561 ret = i915_gem_object_wait_rendering(reg->obj);
1562 if (ret) {
1563 WARN(ret, "wait_rendering failed: %d\n", ret);
1564 return;
1565 }
1566 goto try_again;
1567 }
1568
1569 /*
1570 * Zap this virtual mapping so we can set up a fence again
1571 * for this object next time we need it.
1572 */
1573 offset = ((loff_t) reg->obj->map_list.hash.key) << PAGE_SHIFT;
1574 if (dev->dev_mapping)
1575 unmap_mapping_range(dev->dev_mapping, offset,
1576 reg->obj->size, 1);
1577 old_obj_priv->fence_reg = I915_FENCE_REG_NONE;
1578 }
1579
1580 obj_priv->fence_reg = i;
1581 reg->obj = obj;
1582
1583 if (IS_I965G(dev))
1584 i965_write_fence_reg(reg);
1585 else if (IS_I9XX(dev))
1586 i915_write_fence_reg(reg);
1587 else
1588 i830_write_fence_reg(reg);
1589}
1590
1591/**
1592 * i915_gem_clear_fence_reg - clear out fence register info
1593 * @obj: object to clear
1594 *
1595 * Zeroes out the fence register itself and clears out the associated
1596 * data structures in dev_priv and obj_priv.
1597 */
1598static void
1599i915_gem_clear_fence_reg(struct drm_gem_object *obj)
1600{
1601 struct drm_device *dev = obj->dev;
1602 drm_i915_private_t *dev_priv = dev->dev_private;
1603 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1604
1605 if (IS_I965G(dev))
1606 I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0);
1607 else
1608 I915_WRITE(FENCE_REG_830_0 + (obj_priv->fence_reg * 4), 0);
1609
1610 dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL;
1611 obj_priv->fence_reg = I915_FENCE_REG_NONE;
1612}
1613
1152/** 1614/**
1153 * Finds free space in the GTT aperture and binds the object there. 1615 * Finds free space in the GTT aperture and binds the object there.
1154 */ 1616 */
@@ -1307,7 +1769,7 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj)
1307 * This function returns when the move is complete, including waiting on 1769 * This function returns when the move is complete, including waiting on
1308 * flushes to occur. 1770 * flushes to occur.
1309 */ 1771 */
1310static int 1772int
1311i915_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)
1312{ 1774{
1313 struct drm_i915_gem_object *obj_priv = obj->driver_private; 1775 struct drm_i915_gem_object *obj_priv = obj->driver_private;
@@ -2029,13 +2491,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2029 2491
2030 /* error other than GTT full, or we've already tried again */ 2492 /* error other than GTT full, or we've already tried again */
2031 if (ret != -ENOMEM || pin_tries >= 1) { 2493 if (ret != -ENOMEM || pin_tries >= 1) {
2032 DRM_ERROR("Failed to pin buffers %d\n", ret); 2494 if (ret != -ERESTARTSYS)
2495 DRM_ERROR("Failed to pin buffers %d\n", ret);
2033 goto err; 2496 goto err;
2034 } 2497 }
2035 2498
2036 /* unpin all of our buffers */ 2499 /* unpin all of our buffers */
2037 for (i = 0; i < pinned; i++) 2500 for (i = 0; i < pinned; i++)
2038 i915_gem_object_unpin(object_list[i]); 2501 i915_gem_object_unpin(object_list[i]);
2502 pinned = 0;
2039 2503
2040 /* evict everyone we can from the aperture */ 2504 /* evict everyone we can from the aperture */
2041 ret = i915_gem_evict_everything(dev); 2505 ret = i915_gem_evict_everything(dev);
@@ -2149,13 +2613,12 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2149 "back to user (%d)\n", 2613 "back to user (%d)\n",
2150 args->buffer_count, ret); 2614 args->buffer_count, ret);
2151err: 2615err:
2152 if (object_list != NULL) { 2616 for (i = 0; i < pinned; i++)
2153 for (i = 0; i < pinned; i++) 2617 i915_gem_object_unpin(object_list[i]);
2154 i915_gem_object_unpin(object_list[i]); 2618
2619 for (i = 0; i < args->buffer_count; i++)
2620 drm_gem_object_unreference(object_list[i]);
2155 2621
2156 for (i = 0; i < args->buffer_count; i++)
2157 drm_gem_object_unreference(object_list[i]);
2158 }
2159 mutex_unlock(&dev->struct_mutex); 2622 mutex_unlock(&dev->struct_mutex);
2160 2623
2161pre_mutex_err: 2624pre_mutex_err:
@@ -2178,7 +2641,8 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
2178 if (obj_priv->gtt_space == NULL) { 2641 if (obj_priv->gtt_space == NULL) {
2179 ret = i915_gem_object_bind_to_gtt(obj, alignment); 2642 ret = i915_gem_object_bind_to_gtt(obj, alignment);
2180 if (ret != 0) { 2643 if (ret != 0) {
2181 DRM_ERROR("Failure to bind: %d", ret); 2644 if (ret != -ERESTARTSYS)
2645 DRM_ERROR("Failure to bind: %d", ret);
2182 return ret; 2646 return ret;
2183 } 2647 }
2184 } 2648 }
@@ -2249,11 +2713,22 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
2249 } 2713 }
2250 obj_priv = obj->driver_private; 2714 obj_priv = obj->driver_private;
2251 2715
2252 ret = i915_gem_object_pin(obj, args->alignment); 2716 if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) {
2253 if (ret != 0) { 2717 DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n",
2254 drm_gem_object_unreference(obj); 2718 args->handle);
2255 mutex_unlock(&dev->struct_mutex); 2719 mutex_unlock(&dev->struct_mutex);
2256 return ret; 2720 return -EINVAL;
2721 }
2722
2723 obj_priv->user_pin_count++;
2724 obj_priv->pin_filp = file_priv;
2725 if (obj_priv->user_pin_count == 1) {
2726 ret = i915_gem_object_pin(obj, args->alignment);
2727 if (ret != 0) {
2728 drm_gem_object_unreference(obj);
2729 mutex_unlock(&dev->struct_mutex);
2730 return ret;
2731 }
2257 } 2732 }
2258 2733
2259 /* XXX - flush the CPU caches for pinned objects 2734 /* XXX - flush the CPU caches for pinned objects
@@ -2273,6 +2748,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
2273{ 2748{
2274 struct drm_i915_gem_pin *args = data; 2749 struct drm_i915_gem_pin *args = data;
2275 struct drm_gem_object *obj; 2750 struct drm_gem_object *obj;
2751 struct drm_i915_gem_object *obj_priv;
2276 2752
2277 mutex_lock(&dev->struct_mutex); 2753 mutex_lock(&dev->struct_mutex);
2278 2754
@@ -2284,7 +2760,19 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
2284 return -EBADF; 2760 return -EBADF;
2285 } 2761 }
2286 2762
2287 i915_gem_object_unpin(obj); 2763 obj_priv = obj->driver_private;
2764 if (obj_priv->pin_filp != file_priv) {
2765 DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
2766 args->handle);
2767 drm_gem_object_unreference(obj);
2768 mutex_unlock(&dev->struct_mutex);
2769 return -EINVAL;
2770 }
2771 obj_priv->user_pin_count--;
2772 if (obj_priv->user_pin_count == 0) {
2773 obj_priv->pin_filp = NULL;
2774 i915_gem_object_unpin(obj);
2775 }
2288 2776
2289 drm_gem_object_unreference(obj); 2777 drm_gem_object_unreference(obj);
2290 mutex_unlock(&dev->struct_mutex); 2778 mutex_unlock(&dev->struct_mutex);
@@ -2351,12 +2839,18 @@ int i915_gem_init_object(struct drm_gem_object *obj)
2351 2839
2352 obj->driver_private = obj_priv; 2840 obj->driver_private = obj_priv;
2353 obj_priv->obj = obj; 2841 obj_priv->obj = obj;
2842 obj_priv->fence_reg = I915_FENCE_REG_NONE;
2354 INIT_LIST_HEAD(&obj_priv->list); 2843 INIT_LIST_HEAD(&obj_priv->list);
2844
2355 return 0; 2845 return 0;
2356} 2846}
2357 2847
2358void i915_gem_free_object(struct drm_gem_object *obj) 2848void i915_gem_free_object(struct drm_gem_object *obj)
2359{ 2849{
2850 struct drm_device *dev = obj->dev;
2851 struct drm_gem_mm *mm = dev->mm_private;
2852 struct drm_map_list *list;
2853 struct drm_map *map;
2360 struct drm_i915_gem_object *obj_priv = obj->driver_private; 2854 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2361 2855
2362 while (obj_priv->pin_count > 0) 2856 while (obj_priv->pin_count > 0)
@@ -2364,6 +2858,20 @@ void i915_gem_free_object(struct drm_gem_object *obj)
2364 2858
2365 i915_gem_object_unbind(obj); 2859 i915_gem_object_unbind(obj);
2366 2860
2861 list = &obj->map_list;
2862 drm_ht_remove_item(&mm->offset_hash, &list->hash);
2863
2864 if (list->file_offset_node) {
2865 drm_mm_put_block(list->file_offset_node);
2866 list->file_offset_node = NULL;
2867 }
2868
2869 map = list->map;
2870 if (map) {
2871 drm_free(map, sizeof(*map), DRM_MEM_DRIVER);
2872 list->map = NULL;
2873 }
2874
2367 drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); 2875 drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
2368 drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); 2876 drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
2369} 2877}
@@ -2432,8 +2940,7 @@ i915_gem_idle(struct drm_device *dev)
2432 */ 2940 */
2433 i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT), 2941 i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT),
2434 ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)); 2942 ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2435 seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU | 2943 seqno = i915_add_request(dev, ~I915_GEM_DOMAIN_CPU);
2436 I915_GEM_DOMAIN_GTT));
2437 2944
2438 if (seqno == 0) { 2945 if (seqno == 0) {
2439 mutex_unlock(&dev->struct_mutex); 2946 mutex_unlock(&dev->struct_mutex);
@@ -2560,12 +3067,13 @@ i915_gem_init_hws(struct drm_device *dev)
2560 return 0; 3067 return 0;
2561} 3068}
2562 3069
2563static int 3070int
2564i915_gem_init_ringbuffer(struct drm_device *dev) 3071i915_gem_init_ringbuffer(struct drm_device *dev)
2565{ 3072{
2566 drm_i915_private_t *dev_priv = dev->dev_private; 3073 drm_i915_private_t *dev_priv = dev->dev_private;
2567 struct drm_gem_object *obj; 3074 struct drm_gem_object *obj;
2568 struct drm_i915_gem_object *obj_priv; 3075 struct drm_i915_gem_object *obj_priv;
3076 drm_i915_ring_buffer_t *ring = &dev_priv->ring;
2569 int ret; 3077 int ret;
2570 u32 head; 3078 u32 head;
2571 3079
@@ -2587,24 +3095,24 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
2587 } 3095 }
2588 3096
2589 /* Set up the kernel mapping for the ring. */ 3097 /* Set up the kernel mapping for the ring. */
2590 dev_priv->ring.Size = obj->size; 3098 ring->Size = obj->size;
2591 dev_priv->ring.tail_mask = obj->size - 1; 3099 ring->tail_mask = obj->size - 1;
2592 3100
2593 dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset; 3101 ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
2594 dev_priv->ring.map.size = obj->size; 3102 ring->map.size = obj->size;
2595 dev_priv->ring.map.type = 0; 3103 ring->map.type = 0;
2596 dev_priv->ring.map.flags = 0; 3104 ring->map.flags = 0;
2597 dev_priv->ring.map.mtrr = 0; 3105 ring->map.mtrr = 0;
2598 3106
2599 drm_core_ioremap_wc(&dev_priv->ring.map, dev); 3107 drm_core_ioremap_wc(&ring->map, dev);
2600 if (dev_priv->ring.map.handle == NULL) { 3108 if (ring->map.handle == NULL) {
2601 DRM_ERROR("Failed to map ringbuffer.\n"); 3109 DRM_ERROR("Failed to map ringbuffer.\n");
2602 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); 3110 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
2603 drm_gem_object_unreference(obj); 3111 drm_gem_object_unreference(obj);
2604 return -EINVAL; 3112 return -EINVAL;
2605 } 3113 }
2606 dev_priv->ring.ring_obj = obj; 3114 ring->ring_obj = obj;
2607 dev_priv->ring.virtual_start = dev_priv->ring.map.handle; 3115 ring->virtual_start = ring->map.handle;
2608 3116
2609 /* Stop the ring if it's running. */ 3117 /* Stop the ring if it's running. */
2610 I915_WRITE(PRB0_CTL, 0); 3118 I915_WRITE(PRB0_CTL, 0);
@@ -2652,12 +3160,20 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
2652 } 3160 }
2653 3161
2654 /* Update our cache of the ring state */ 3162 /* Update our cache of the ring state */
2655 i915_kernel_lost_context(dev); 3163 if (!drm_core_check_feature(dev, DRIVER_MODESET))
3164 i915_kernel_lost_context(dev);
3165 else {
3166 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
3167 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
3168 ring->space = ring->head - (ring->tail + 8);
3169 if (ring->space < 0)
3170 ring->space += ring->Size;
3171 }
2656 3172
2657 return 0; 3173 return 0;
2658} 3174}
2659 3175
2660static void 3176void
2661i915_gem_cleanup_ringbuffer(struct drm_device *dev) 3177i915_gem_cleanup_ringbuffer(struct drm_device *dev)
2662{ 3178{
2663 drm_i915_private_t *dev_priv = dev->dev_private; 3179 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -2695,6 +3211,9 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
2695 drm_i915_private_t *dev_priv = dev->dev_private; 3211 drm_i915_private_t *dev_priv = dev->dev_private;
2696 int ret; 3212 int ret;
2697 3213
3214 if (drm_core_check_feature(dev, DRIVER_MODESET))
3215 return 0;
3216
2698 if (dev_priv->mm.wedged) { 3217 if (dev_priv->mm.wedged) {
2699 DRM_ERROR("Reenabling wedged hardware, good luck\n"); 3218 DRM_ERROR("Reenabling wedged hardware, good luck\n");
2700 dev_priv->mm.wedged = 0; 3219 dev_priv->mm.wedged = 0;
@@ -2728,6 +3247,9 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
2728 drm_i915_private_t *dev_priv = dev->dev_private; 3247 drm_i915_private_t *dev_priv = dev->dev_private;
2729 int ret; 3248 int ret;
2730 3249
3250 if (drm_core_check_feature(dev, DRIVER_MODESET))
3251 return 0;
3252
2731 ret = i915_gem_idle(dev); 3253 ret = i915_gem_idle(dev);
2732 drm_irq_uninstall(dev); 3254 drm_irq_uninstall(dev);
2733 3255
@@ -2758,5 +3280,13 @@ i915_gem_load(struct drm_device *dev)
2758 i915_gem_retire_work_handler); 3280 i915_gem_retire_work_handler);
2759 dev_priv->mm.next_gem_seqno = 1; 3281 dev_priv->mm.next_gem_seqno = 1;
2760 3282
3283 /* Old X drivers will take 0-2 for front, back, depth buffers */
3284 dev_priv->fence_reg_start = 3;
3285
3286 if (IS_I965G(dev))
3287 dev_priv->num_fence_regs = 16;
3288 else
3289 dev_priv->num_fence_regs = 8;
3290
2761 i915_gem_detect_bit_6_swizzle(dev); 3291 i915_gem_detect_bit_6_swizzle(dev);
2762} 3292}
diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c
index e8d5abe1250e..4d1b9de0cd8b 100644
--- a/drivers/gpu/drm/i915/i915_gem_proc.c
+++ b/drivers/gpu/drm/i915/i915_gem_proc.c
@@ -250,6 +250,39 @@ static int i915_interrupt_info(char *buf, char **start, off_t offset,
250 return len - offset; 250 return len - offset;
251} 251}
252 252
253static int i915_hws_info(char *buf, char **start, off_t offset,
254 int request, int *eof, void *data)
255{
256 struct drm_minor *minor = (struct drm_minor *) data;
257 struct drm_device *dev = minor->dev;
258 drm_i915_private_t *dev_priv = dev->dev_private;
259 int len = 0, i;
260 volatile u32 *hws;
261
262 if (offset > DRM_PROC_LIMIT) {
263 *eof = 1;
264 return 0;
265 }
266
267 hws = (volatile u32 *)dev_priv->hw_status_page;
268 if (hws == NULL) {
269 *eof = 1;
270 return 0;
271 }
272
273 *start = &buf[offset];
274 *eof = 0;
275 for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
276 DRM_PROC_PRINT("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
277 i * 4,
278 hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
279 }
280 if (len > request + offset)
281 return request;
282 *eof = 1;
283 return len - offset;
284}
285
253static struct drm_proc_list { 286static struct drm_proc_list {
254 /** file name */ 287 /** file name */
255 const char *name; 288 const char *name;
@@ -262,6 +295,7 @@ static struct drm_proc_list {
262 {"i915_gem_request", i915_gem_request_info}, 295 {"i915_gem_request", i915_gem_request_info},
263 {"i915_gem_seqno", i915_gem_seqno_info}, 296 {"i915_gem_seqno", i915_gem_seqno_info},
264 {"i915_gem_interrupt", i915_interrupt_info}, 297 {"i915_gem_interrupt", i915_interrupt_info},
298 {"i915_gem_hws", i915_hws_info},
265}; 299};
266 300
267#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list) 301#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index a8cb69469c64..241f39b7f460 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -208,6 +208,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
208 } 208 }
209 } 209 }
210 obj_priv->tiling_mode = args->tiling_mode; 210 obj_priv->tiling_mode = args->tiling_mode;
211 obj_priv->stride = args->stride;
211 212
212 mutex_unlock(&dev->struct_mutex); 213 mutex_unlock(&dev->struct_mutex);
213 214
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 69b9a42da95e..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{
@@ -168,6 +178,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
168{ 178{
169 struct drm_device *dev = (struct drm_device *) arg; 179 struct drm_device *dev = (struct drm_device *) arg;
170 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 180 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
181 struct drm_i915_master_private *master_priv;
171 u32 iir, new_iir; 182 u32 iir, new_iir;
172 u32 pipea_stats, pipeb_stats; 183 u32 pipea_stats, pipeb_stats;
173 u32 vblank_status; 184 u32 vblank_status;
@@ -200,6 +211,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
200 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 211 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
201 pipea_stats = I915_READ(PIPEASTAT); 212 pipea_stats = I915_READ(PIPEASTAT);
202 pipeb_stats = I915_READ(PIPEBSTAT); 213 pipeb_stats = I915_READ(PIPEBSTAT);
214
203 /* 215 /*
204 * Clear the PIPE(A|B)STAT regs before the IIR 216 * Clear the PIPE(A|B)STAT regs before the IIR
205 */ 217 */
@@ -222,9 +234,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
222 I915_WRITE(IIR, iir); 234 I915_WRITE(IIR, iir);
223 new_iir = I915_READ(IIR); /* Flush posted writes */ 235 new_iir = I915_READ(IIR); /* Flush posted writes */
224 236
225 if (dev_priv->sarea_priv) 237 if (dev->primary->master) {
226 dev_priv->sarea_priv->last_dispatch = 238 master_priv = dev->primary->master->driver_priv;
227 READ_BREADCRUMB(dev_priv); 239 if (master_priv->sarea_priv)
240 master_priv->sarea_priv->last_dispatch =
241 READ_BREADCRUMB(dev_priv);
242 }
228 243
229 if (iir & I915_USER_INTERRUPT) { 244 if (iir & I915_USER_INTERRUPT) {
230 dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); 245 dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
@@ -269,6 +284,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
269static int i915_emit_irq(struct drm_device * dev) 284static int i915_emit_irq(struct drm_device * dev)
270{ 285{
271 drm_i915_private_t *dev_priv = dev->dev_private; 286 drm_i915_private_t *dev_priv = dev->dev_private;
287 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
272 RING_LOCALS; 288 RING_LOCALS;
273 289
274 i915_kernel_lost_context(dev); 290 i915_kernel_lost_context(dev);
@@ -278,8 +294,8 @@ static int i915_emit_irq(struct drm_device * dev)
278 dev_priv->counter++; 294 dev_priv->counter++;
279 if (dev_priv->counter > 0x7FFFFFFFUL) 295 if (dev_priv->counter > 0x7FFFFFFFUL)
280 dev_priv->counter = 1; 296 dev_priv->counter = 1;
281 if (dev_priv->sarea_priv) 297 if (master_priv->sarea_priv)
282 dev_priv->sarea_priv->last_enqueue = dev_priv->counter; 298 master_priv->sarea_priv->last_enqueue = dev_priv->counter;
283 299
284 BEGIN_LP_RING(4); 300 BEGIN_LP_RING(4);
285 OUT_RING(MI_STORE_DWORD_INDEX); 301 OUT_RING(MI_STORE_DWORD_INDEX);
@@ -317,21 +333,20 @@ void i915_user_irq_put(struct drm_device *dev)
317static int i915_wait_irq(struct drm_device * dev, int irq_nr) 333static int i915_wait_irq(struct drm_device * dev, int irq_nr)
318{ 334{
319 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 335 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
336 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
320 int ret = 0; 337 int ret = 0;
321 338
322 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr, 339 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
323 READ_BREADCRUMB(dev_priv)); 340 READ_BREADCRUMB(dev_priv));
324 341
325 if (READ_BREADCRUMB(dev_priv) >= irq_nr) { 342 if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
326 if (dev_priv->sarea_priv) { 343 if (master_priv->sarea_priv)
327 dev_priv->sarea_priv->last_dispatch = 344 master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
328 READ_BREADCRUMB(dev_priv);
329 }
330 return 0; 345 return 0;
331 } 346 }
332 347
333 if (dev_priv->sarea_priv) 348 if (master_priv->sarea_priv)
334 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 349 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
335 350
336 i915_user_irq_get(dev); 351 i915_user_irq_get(dev);
337 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, 352 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
@@ -343,10 +358,6 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
343 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); 358 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
344 } 359 }
345 360
346 if (dev_priv->sarea_priv)
347 dev_priv->sarea_priv->last_dispatch =
348 READ_BREADCRUMB(dev_priv);
349
350 return ret; 361 return ret;
351} 362}
352 363
@@ -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/i915_mem.c b/drivers/gpu/drm/i915/i915_mem.c
index 6126a60dc9cb..96e271986d2a 100644
--- a/drivers/gpu/drm/i915/i915_mem.c
+++ b/drivers/gpu/drm/i915/i915_mem.c
@@ -46,7 +46,8 @@
46static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use) 46static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use)
47{ 47{
48 drm_i915_private_t *dev_priv = dev->dev_private; 48 drm_i915_private_t *dev_priv = dev->dev_private;
49 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; 49 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
50 drm_i915_sarea_t *sarea_priv = master_priv->sarea_priv;
50 struct drm_tex_region *list; 51 struct drm_tex_region *list;
51 unsigned shift, nr; 52 unsigned shift, nr;
52 unsigned start; 53 unsigned start;
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 13ae731a33db..ff012835a386 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -257,8 +257,8 @@ void opregion_enable_asle(struct drm_device *dev)
257 257
258static struct intel_opregion *system_opregion; 258static struct intel_opregion *system_opregion;
259 259
260int intel_opregion_video_event(struct notifier_block *nb, unsigned long val, 260static int intel_opregion_video_event(struct notifier_block *nb,
261 void *data) 261 unsigned long val, void *data)
262{ 262{
263 /* The only video events relevant to opregion are 0x80. These indicate 263 /* The only video events relevant to opregion are 0x80. These indicate
264 either a docking event, lid switch or display switch request. In 264 either a docking event, lid switch or display switch request. In
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9d24aaeb8a45..47e6bafeb743 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -175,9 +175,26 @@
175#define DISPLAY_PLANE_B (1<<20) 175#define DISPLAY_PLANE_B (1<<20)
176 176
177/* 177/*
178 * Instruction and interrupt control regs 178 * Fence registers
179 */ 179 */
180#define FENCE_REG_830_0 0x2000
181#define I830_FENCE_START_MASK 0x07f80000
182#define I830_FENCE_TILING_Y_SHIFT 12
183#define I830_FENCE_SIZE_BITS(size) ((get_order(size >> 19) - 1) << 8)
184#define I830_FENCE_PITCH_SHIFT 4
185#define I830_FENCE_REG_VALID (1<<0)
186
187#define I915_FENCE_START_MASK 0x0ff00000
188#define I915_FENCE_SIZE_BITS(size) ((get_order(size >> 20) - 1) << 8)
180 189
190#define FENCE_REG_965_0 0x03000
191#define I965_FENCE_PITCH_SHIFT 2
192#define I965_FENCE_TILING_Y_SHIFT 1
193#define I965_FENCE_REG_VALID (1<<0)
194
195/*
196 * Instruction and interrupt control regs
197 */
181#define PRB0_TAIL 0x02030 198#define PRB0_TAIL 0x02030
182#define PRB0_HEAD 0x02034 199#define PRB0_HEAD 0x02034
183#define PRB0_START 0x02038 200#define PRB0_START 0x02038
@@ -245,6 +262,7 @@
245#define CM0_RC_OP_FLUSH_DISABLE (1<<0) 262#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
246#define GFX_FLSH_CNTL 0x02170 /* 915+ only */ 263#define GFX_FLSH_CNTL 0x02170 /* 915+ only */
247 264
265
248/* 266/*
249 * Framebuffer compression (915+ only) 267 * Framebuffer compression (915+ only)
250 */ 268 */
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..dcaed3466e83
--- /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
240static void 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..e5c1c80d1f90
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -0,0 +1,1618 @@
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 i9xx_clock (refclk, clock);
217 else
218 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
346static void
347intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
348 struct drm_framebuffer *old_fb)
349{
350 struct drm_device *dev = crtc->dev;
351 struct drm_i915_private *dev_priv = dev->dev_private;
352 struct drm_i915_master_private *master_priv;
353 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
354 struct intel_framebuffer *intel_fb;
355 struct drm_i915_gem_object *obj_priv;
356 struct drm_gem_object *obj;
357 int pipe = intel_crtc->pipe;
358 unsigned long Start, Offset;
359 int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
360 int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
361 int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
362 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
363 u32 dspcntr, alignment;
364
365 /* no fb bound */
366 if (!crtc->fb) {
367 DRM_DEBUG("No FB bound\n");
368 return;
369 }
370
371 intel_fb = to_intel_framebuffer(crtc->fb);
372 obj = intel_fb->obj;
373 obj_priv = obj->driver_private;
374
375 switch (obj_priv->tiling_mode) {
376 case I915_TILING_NONE:
377 alignment = 64 * 1024;
378 break;
379 case I915_TILING_X:
380 if (IS_I9XX(dev))
381 alignment = 1024 * 1024;
382 else
383 alignment = 512 * 1024;
384 break;
385 case I915_TILING_Y:
386 /* FIXME: Is this true? */
387 DRM_ERROR("Y tiled not allowed for scan out buffers\n");
388 return;
389 default:
390 BUG();
391 }
392
393 if (i915_gem_object_pin(intel_fb->obj, alignment))
394 return;
395
396 i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
397
398 Start = obj_priv->gtt_offset;
399 Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
400
401 I915_WRITE(dspstride, crtc->fb->pitch);
402
403 dspcntr = I915_READ(dspcntr_reg);
404 switch (crtc->fb->bits_per_pixel) {
405 case 8:
406 dspcntr |= DISPPLANE_8BPP;
407 break;
408 case 16:
409 if (crtc->fb->depth == 15)
410 dspcntr |= DISPPLANE_15_16BPP;
411 else
412 dspcntr |= DISPPLANE_16BPP;
413 break;
414 case 24:
415 case 32:
416 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
417 break;
418 default:
419 DRM_ERROR("Unknown color depth\n");
420 return;
421 }
422 I915_WRITE(dspcntr_reg, dspcntr);
423
424 DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
425 if (IS_I965G(dev)) {
426 I915_WRITE(dspbase, Offset);
427 I915_READ(dspbase);
428 I915_WRITE(dspsurf, Start);
429 I915_READ(dspsurf);
430 } else {
431 I915_WRITE(dspbase, Start + Offset);
432 I915_READ(dspbase);
433 }
434
435 intel_wait_for_vblank(dev);
436
437 if (old_fb) {
438 intel_fb = to_intel_framebuffer(old_fb);
439 i915_gem_object_unpin(intel_fb->obj);
440 }
441
442 if (!dev->primary->master)
443 return;
444
445 master_priv = dev->primary->master->driver_priv;
446 if (!master_priv->sarea_priv)
447 return;
448
449 switch (pipe) {
450 case 0:
451 master_priv->sarea_priv->pipeA_x = x;
452 master_priv->sarea_priv->pipeA_y = y;
453 break;
454 case 1:
455 master_priv->sarea_priv->pipeB_x = x;
456 master_priv->sarea_priv->pipeB_y = y;
457 break;
458 default:
459 DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
460 break;
461 }
462}
463
464
465
466/**
467 * Sets the power management mode of the pipe and plane.
468 *
469 * This code should probably grow support for turning the cursor off and back
470 * on appropriately at the same time as we're turning the pipe off/on.
471 */
472static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
473{
474 struct drm_device *dev = crtc->dev;
475 struct drm_i915_master_private *master_priv;
476 struct drm_i915_private *dev_priv = dev->dev_private;
477 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
478 int pipe = intel_crtc->pipe;
479 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
480 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
481 int dspbase_reg = (pipe == 0) ? DSPAADDR : DSPBADDR;
482 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
483 u32 temp;
484 bool enabled;
485
486 /* XXX: When our outputs are all unaware of DPMS modes other than off
487 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
488 */
489 switch (mode) {
490 case DRM_MODE_DPMS_ON:
491 case DRM_MODE_DPMS_STANDBY:
492 case DRM_MODE_DPMS_SUSPEND:
493 /* Enable the DPLL */
494 temp = I915_READ(dpll_reg);
495 if ((temp & DPLL_VCO_ENABLE) == 0) {
496 I915_WRITE(dpll_reg, temp);
497 I915_READ(dpll_reg);
498 /* Wait for the clocks to stabilize. */
499 udelay(150);
500 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
501 I915_READ(dpll_reg);
502 /* Wait for the clocks to stabilize. */
503 udelay(150);
504 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
505 I915_READ(dpll_reg);
506 /* Wait for the clocks to stabilize. */
507 udelay(150);
508 }
509
510 /* Enable the pipe */
511 temp = I915_READ(pipeconf_reg);
512 if ((temp & PIPEACONF_ENABLE) == 0)
513 I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
514
515 /* Enable the plane */
516 temp = I915_READ(dspcntr_reg);
517 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
518 I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
519 /* Flush the plane changes */
520 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
521 }
522
523 intel_crtc_load_lut(crtc);
524
525 /* Give the overlay scaler a chance to enable if it's on this pipe */
526 //intel_crtc_dpms_video(crtc, true); TODO
527 break;
528 case DRM_MODE_DPMS_OFF:
529 /* Give the overlay scaler a chance to disable if it's on this pipe */
530 //intel_crtc_dpms_video(crtc, FALSE); TODO
531
532 /* Disable the VGA plane that we never use */
533 I915_WRITE(VGACNTRL, VGA_DISP_DISABLE);
534
535 /* Disable display plane */
536 temp = I915_READ(dspcntr_reg);
537 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
538 I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
539 /* Flush the plane changes */
540 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
541 I915_READ(dspbase_reg);
542 }
543
544 if (!IS_I9XX(dev)) {
545 /* Wait for vblank for the disable to take effect */
546 intel_wait_for_vblank(dev);
547 }
548
549 /* Next, disable display pipes */
550 temp = I915_READ(pipeconf_reg);
551 if ((temp & PIPEACONF_ENABLE) != 0) {
552 I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
553 I915_READ(pipeconf_reg);
554 }
555
556 /* Wait for vblank for the disable to take effect. */
557 intel_wait_for_vblank(dev);
558
559 temp = I915_READ(dpll_reg);
560 if ((temp & DPLL_VCO_ENABLE) != 0) {
561 I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
562 I915_READ(dpll_reg);
563 }
564
565 /* Wait for the clocks to turn off. */
566 udelay(150);
567 break;
568 }
569
570 if (!dev->primary->master)
571 return;
572
573 master_priv = dev->primary->master->driver_priv;
574 if (!master_priv->sarea_priv)
575 return;
576
577 enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
578
579 switch (pipe) {
580 case 0:
581 master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0;
582 master_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0;
583 break;
584 case 1:
585 master_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0;
586 master_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0;
587 break;
588 default:
589 DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
590 break;
591 }
592
593 intel_crtc->dpms_mode = mode;
594}
595
596static void intel_crtc_prepare (struct drm_crtc *crtc)
597{
598 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
599 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
600}
601
602static void intel_crtc_commit (struct drm_crtc *crtc)
603{
604 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
605 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
606}
607
608void intel_encoder_prepare (struct drm_encoder *encoder)
609{
610 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
611 /* lvds has its own version of prepare see intel_lvds_prepare */
612 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
613}
614
615void intel_encoder_commit (struct drm_encoder *encoder)
616{
617 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
618 /* lvds has its own version of commit see intel_lvds_commit */
619 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
620}
621
622static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
623 struct drm_display_mode *mode,
624 struct drm_display_mode *adjusted_mode)
625{
626 return true;
627}
628
629
630/** Returns the core display clock speed for i830 - i945 */
631static int intel_get_core_clock_speed(struct drm_device *dev)
632{
633
634 /* Core clock values taken from the published datasheets.
635 * The 830 may go up to 166 Mhz, which we should check.
636 */
637 if (IS_I945G(dev))
638 return 400000;
639 else if (IS_I915G(dev))
640 return 333000;
641 else if (IS_I945GM(dev) || IS_845G(dev))
642 return 200000;
643 else if (IS_I915GM(dev)) {
644 u16 gcfgc = 0;
645
646 pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
647
648 if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
649 return 133000;
650 else {
651 switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
652 case GC_DISPLAY_CLOCK_333_MHZ:
653 return 333000;
654 default:
655 case GC_DISPLAY_CLOCK_190_200_MHZ:
656 return 190000;
657 }
658 }
659 } else if (IS_I865G(dev))
660 return 266000;
661 else if (IS_I855(dev)) {
662 u16 hpllcc = 0;
663 /* Assume that the hardware is in the high speed state. This
664 * should be the default.
665 */
666 switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
667 case GC_CLOCK_133_200:
668 case GC_CLOCK_100_200:
669 return 200000;
670 case GC_CLOCK_166_250:
671 return 250000;
672 case GC_CLOCK_100_133:
673 return 133000;
674 }
675 } else /* 852, 830 */
676 return 133000;
677
678 return 0; /* Silence gcc warning */
679}
680
681
682/**
683 * Return the pipe currently connected to the panel fitter,
684 * or -1 if the panel fitter is not present or not in use
685 */
686static int intel_panel_fitter_pipe (struct drm_device *dev)
687{
688 struct drm_i915_private *dev_priv = dev->dev_private;
689 u32 pfit_control;
690
691 /* i830 doesn't have a panel fitter */
692 if (IS_I830(dev))
693 return -1;
694
695 pfit_control = I915_READ(PFIT_CONTROL);
696
697 /* See if the panel fitter is in use */
698 if ((pfit_control & PFIT_ENABLE) == 0)
699 return -1;
700
701 /* 965 can place panel fitter on either pipe */
702 if (IS_I965G(dev))
703 return (pfit_control >> 29) & 0x3;
704
705 /* older chips can only use pipe 1 */
706 return 1;
707}
708
709static void intel_crtc_mode_set(struct drm_crtc *crtc,
710 struct drm_display_mode *mode,
711 struct drm_display_mode *adjusted_mode,
712 int x, int y,
713 struct drm_framebuffer *old_fb)
714{
715 struct drm_device *dev = crtc->dev;
716 struct drm_i915_private *dev_priv = dev->dev_private;
717 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
718 int pipe = intel_crtc->pipe;
719 int fp_reg = (pipe == 0) ? FPA0 : FPB0;
720 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
721 int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
722 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
723 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
724 int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
725 int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
726 int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
727 int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
728 int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
729 int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
730 int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
731 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
732 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
733 int refclk;
734 intel_clock_t clock;
735 u32 dpll = 0, fp = 0, dspcntr, pipeconf;
736 bool ok, is_sdvo = false, is_dvo = false;
737 bool is_crt = false, is_lvds = false, is_tv = false;
738 struct drm_mode_config *mode_config = &dev->mode_config;
739 struct drm_connector *connector;
740
741 drm_vblank_pre_modeset(dev, pipe);
742
743 list_for_each_entry(connector, &mode_config->connector_list, head) {
744 struct intel_output *intel_output = to_intel_output(connector);
745
746 if (!connector->encoder || connector->encoder->crtc != crtc)
747 continue;
748
749 switch (intel_output->type) {
750 case INTEL_OUTPUT_LVDS:
751 is_lvds = true;
752 break;
753 case INTEL_OUTPUT_SDVO:
754 is_sdvo = true;
755 break;
756 case INTEL_OUTPUT_DVO:
757 is_dvo = true;
758 break;
759 case INTEL_OUTPUT_TVOUT:
760 is_tv = true;
761 break;
762 case INTEL_OUTPUT_ANALOG:
763 is_crt = true;
764 break;
765 }
766 }
767
768 if (IS_I9XX(dev)) {
769 refclk = 96000;
770 } else {
771 refclk = 48000;
772 }
773
774 ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock);
775 if (!ok) {
776 DRM_ERROR("Couldn't find PLL settings for mode!\n");
777 return;
778 }
779
780 fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
781
782 dpll = DPLL_VGA_MODE_DIS;
783 if (IS_I9XX(dev)) {
784 if (is_lvds)
785 dpll |= DPLLB_MODE_LVDS;
786 else
787 dpll |= DPLLB_MODE_DAC_SERIAL;
788 if (is_sdvo) {
789 dpll |= DPLL_DVO_HIGH_SPEED;
790 if (IS_I945G(dev) || IS_I945GM(dev)) {
791 int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
792 dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
793 }
794 }
795
796 /* compute bitmask from p1 value */
797 dpll |= (1 << (clock.p1 - 1)) << 16;
798 switch (clock.p2) {
799 case 5:
800 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
801 break;
802 case 7:
803 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
804 break;
805 case 10:
806 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
807 break;
808 case 14:
809 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
810 break;
811 }
812 if (IS_I965G(dev))
813 dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
814 } else {
815 if (is_lvds) {
816 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
817 } else {
818 if (clock.p1 == 2)
819 dpll |= PLL_P1_DIVIDE_BY_TWO;
820 else
821 dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
822 if (clock.p2 == 4)
823 dpll |= PLL_P2_DIVIDE_BY_4;
824 }
825 }
826
827 if (is_tv) {
828 /* XXX: just matching BIOS for now */
829/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
830 dpll |= 3;
831 }
832 else
833 dpll |= PLL_REF_INPUT_DREFCLK;
834
835 /* setup pipeconf */
836 pipeconf = I915_READ(pipeconf_reg);
837
838 /* Set up the display plane register */
839 dspcntr = DISPPLANE_GAMMA_ENABLE;
840
841 if (pipe == 0)
842 dspcntr |= DISPPLANE_SEL_PIPE_A;
843 else
844 dspcntr |= DISPPLANE_SEL_PIPE_B;
845
846 if (pipe == 0 && !IS_I965G(dev)) {
847 /* Enable pixel doubling when the dot clock is > 90% of the (display)
848 * core speed.
849 *
850 * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
851 * pipe == 0 check?
852 */
853 if (mode->clock > intel_get_core_clock_speed(dev) * 9 / 10)
854 pipeconf |= PIPEACONF_DOUBLE_WIDE;
855 else
856 pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
857 }
858
859 dspcntr |= DISPLAY_PLANE_ENABLE;
860 pipeconf |= PIPEACONF_ENABLE;
861 dpll |= DPLL_VCO_ENABLE;
862
863
864 /* Disable the panel fitter if it was on our pipe */
865 if (intel_panel_fitter_pipe(dev) == pipe)
866 I915_WRITE(PFIT_CONTROL, 0);
867
868 DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
869 drm_mode_debug_printmodeline(mode);
870
871
872 if (dpll & DPLL_VCO_ENABLE) {
873 I915_WRITE(fp_reg, fp);
874 I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
875 I915_READ(dpll_reg);
876 udelay(150);
877 }
878
879 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
880 * This is an exception to the general rule that mode_set doesn't turn
881 * things on.
882 */
883 if (is_lvds) {
884 u32 lvds = I915_READ(LVDS);
885
886 lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
887 /* Set the B0-B3 data pairs corresponding to whether we're going to
888 * set the DPLLs for dual-channel mode or not.
889 */
890 if (clock.p2 == 7)
891 lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
892 else
893 lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
894
895 /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
896 * appropriately here, but we need to look more thoroughly into how
897 * panels behave in the two modes.
898 */
899
900 I915_WRITE(LVDS, lvds);
901 I915_READ(LVDS);
902 }
903
904 I915_WRITE(fp_reg, fp);
905 I915_WRITE(dpll_reg, dpll);
906 I915_READ(dpll_reg);
907 /* Wait for the clocks to stabilize. */
908 udelay(150);
909
910 if (IS_I965G(dev)) {
911 int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
912 I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
913 ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
914 } else {
915 /* write it again -- the BIOS does, after all */
916 I915_WRITE(dpll_reg, dpll);
917 }
918 I915_READ(dpll_reg);
919 /* Wait for the clocks to stabilize. */
920 udelay(150);
921
922 I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
923 ((adjusted_mode->crtc_htotal - 1) << 16));
924 I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
925 ((adjusted_mode->crtc_hblank_end - 1) << 16));
926 I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
927 ((adjusted_mode->crtc_hsync_end - 1) << 16));
928 I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
929 ((adjusted_mode->crtc_vtotal - 1) << 16));
930 I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
931 ((adjusted_mode->crtc_vblank_end - 1) << 16));
932 I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
933 ((adjusted_mode->crtc_vsync_end - 1) << 16));
934 /* pipesrc and dspsize control the size that is scaled from, which should
935 * always be the user's requested size.
936 */
937 I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
938 I915_WRITE(dsppos_reg, 0);
939 I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
940 I915_WRITE(pipeconf_reg, pipeconf);
941 I915_READ(pipeconf_reg);
942
943 intel_wait_for_vblank(dev);
944
945 I915_WRITE(dspcntr_reg, dspcntr);
946
947 /* Flush the plane changes */
948 intel_pipe_set_base(crtc, x, y, old_fb);
949
950 drm_vblank_post_modeset(dev, pipe);
951}
952
953/** Loads the palette/gamma unit for the CRTC with the prepared values */
954void intel_crtc_load_lut(struct drm_crtc *crtc)
955{
956 struct drm_device *dev = crtc->dev;
957 struct drm_i915_private *dev_priv = dev->dev_private;
958 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
959 int palreg = (intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B;
960 int i;
961
962 /* The clocks have to be on to load the palette. */
963 if (!crtc->enabled)
964 return;
965
966 for (i = 0; i < 256; i++) {
967 I915_WRITE(palreg + 4 * i,
968 (intel_crtc->lut_r[i] << 16) |
969 (intel_crtc->lut_g[i] << 8) |
970 intel_crtc->lut_b[i]);
971 }
972}
973
974static int intel_crtc_cursor_set(struct drm_crtc *crtc,
975 struct drm_file *file_priv,
976 uint32_t handle,
977 uint32_t width, uint32_t height)
978{
979 struct drm_device *dev = crtc->dev;
980 struct drm_i915_private *dev_priv = dev->dev_private;
981 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
982 struct drm_gem_object *bo;
983 struct drm_i915_gem_object *obj_priv;
984 int pipe = intel_crtc->pipe;
985 uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
986 uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
987 uint32_t temp;
988 size_t addr;
989
990 DRM_DEBUG("\n");
991
992 /* if we want to turn off the cursor ignore width and height */
993 if (!handle) {
994 DRM_DEBUG("cursor off\n");
995 /* turn of the cursor */
996 temp = 0;
997 temp |= CURSOR_MODE_DISABLE;
998
999 I915_WRITE(control, temp);
1000 I915_WRITE(base, 0);
1001 return 0;
1002 }
1003
1004 /* Currently we only support 64x64 cursors */
1005 if (width != 64 || height != 64) {
1006 DRM_ERROR("we currently only support 64x64 cursors\n");
1007 return -EINVAL;
1008 }
1009
1010 bo = drm_gem_object_lookup(dev, file_priv, handle);
1011 if (!bo)
1012 return -ENOENT;
1013
1014 obj_priv = bo->driver_private;
1015
1016 if (bo->size < width * height * 4) {
1017 DRM_ERROR("buffer is to small\n");
1018 drm_gem_object_unreference(bo);
1019 return -ENOMEM;
1020 }
1021
1022 if (dev_priv->cursor_needs_physical) {
1023 addr = dev->agp->base + obj_priv->gtt_offset;
1024 } else {
1025 addr = obj_priv->gtt_offset;
1026 }
1027
1028 intel_crtc->cursor_addr = addr;
1029 temp = 0;
1030 /* set the pipe for the cursor */
1031 temp |= (pipe << 28);
1032 temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
1033
1034 I915_WRITE(control, temp);
1035 I915_WRITE(base, addr);
1036
1037 return 0;
1038}
1039
1040static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
1041{
1042 struct drm_device *dev = crtc->dev;
1043 struct drm_i915_private *dev_priv = dev->dev_private;
1044 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1045 int pipe = intel_crtc->pipe;
1046 uint32_t temp = 0;
1047 uint32_t adder;
1048
1049 if (x < 0) {
1050 temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
1051 x = -x;
1052 }
1053 if (y < 0) {
1054 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
1055 y = -y;
1056 }
1057
1058 temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
1059 temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1060
1061 adder = intel_crtc->cursor_addr;
1062 I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
1063 I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
1064
1065 return 0;
1066}
1067
1068/** Sets the color ramps on behalf of RandR */
1069void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
1070 u16 blue, int regno)
1071{
1072 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1073
1074 intel_crtc->lut_r[regno] = red >> 8;
1075 intel_crtc->lut_g[regno] = green >> 8;
1076 intel_crtc->lut_b[regno] = blue >> 8;
1077}
1078
1079static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1080 u16 *blue, uint32_t size)
1081{
1082 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1083 int i;
1084
1085 if (size != 256)
1086 return;
1087
1088 for (i = 0; i < 256; i++) {
1089 intel_crtc->lut_r[i] = red[i] >> 8;
1090 intel_crtc->lut_g[i] = green[i] >> 8;
1091 intel_crtc->lut_b[i] = blue[i] >> 8;
1092 }
1093
1094 intel_crtc_load_lut(crtc);
1095}
1096
1097/**
1098 * Get a pipe with a simple mode set on it for doing load-based monitor
1099 * detection.
1100 *
1101 * It will be up to the load-detect code to adjust the pipe as appropriate for
1102 * its requirements. The pipe will be connected to no other outputs.
1103 *
1104 * Currently this code will only succeed if there is a pipe with no outputs
1105 * configured for it. In the future, it could choose to temporarily disable
1106 * some outputs to free up a pipe for its use.
1107 *
1108 * \return crtc, or NULL if no pipes are available.
1109 */
1110
1111/* VESA 640x480x72Hz mode to set on the pipe */
1112static struct drm_display_mode load_detect_mode = {
1113 DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664,
1114 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
1115};
1116
1117struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
1118 struct drm_display_mode *mode,
1119 int *dpms_mode)
1120{
1121 struct intel_crtc *intel_crtc;
1122 struct drm_crtc *possible_crtc;
1123 struct drm_crtc *supported_crtc =NULL;
1124 struct drm_encoder *encoder = &intel_output->enc;
1125 struct drm_crtc *crtc = NULL;
1126 struct drm_device *dev = encoder->dev;
1127 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
1128 struct drm_crtc_helper_funcs *crtc_funcs;
1129 int i = -1;
1130
1131 /*
1132 * Algorithm gets a little messy:
1133 * - if the connector already has an assigned crtc, use it (but make
1134 * sure it's on first)
1135 * - try to find the first unused crtc that can drive this connector,
1136 * and use that if we find one
1137 * - if there are no unused crtcs available, try to use the first
1138 * one we found that supports the connector
1139 */
1140
1141 /* See if we already have a CRTC for this connector */
1142 if (encoder->crtc) {
1143 crtc = encoder->crtc;
1144 /* Make sure the crtc and connector are running */
1145 intel_crtc = to_intel_crtc(crtc);
1146 *dpms_mode = intel_crtc->dpms_mode;
1147 if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
1148 crtc_funcs = crtc->helper_private;
1149 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1150 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
1151 }
1152 return crtc;
1153 }
1154
1155 /* Find an unused one (if possible) */
1156 list_for_each_entry(possible_crtc, &dev->mode_config.crtc_list, head) {
1157 i++;
1158 if (!(encoder->possible_crtcs & (1 << i)))
1159 continue;
1160 if (!possible_crtc->enabled) {
1161 crtc = possible_crtc;
1162 break;
1163 }
1164 if (!supported_crtc)
1165 supported_crtc = possible_crtc;
1166 }
1167
1168 /*
1169 * If we didn't find an unused CRTC, don't use any.
1170 */
1171 if (!crtc) {
1172 return NULL;
1173 }
1174
1175 encoder->crtc = crtc;
1176 intel_output->load_detect_temp = true;
1177
1178 intel_crtc = to_intel_crtc(crtc);
1179 *dpms_mode = intel_crtc->dpms_mode;
1180
1181 if (!crtc->enabled) {
1182 if (!mode)
1183 mode = &load_detect_mode;
1184 drm_crtc_helper_set_mode(crtc, mode, 0, 0, crtc->fb);
1185 } else {
1186 if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
1187 crtc_funcs = crtc->helper_private;
1188 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1189 }
1190
1191 /* Add this connector to the crtc */
1192 encoder_funcs->mode_set(encoder, &crtc->mode, &crtc->mode);
1193 encoder_funcs->commit(encoder);
1194 }
1195 /* let the connector get through one full cycle before testing */
1196 intel_wait_for_vblank(dev);
1197
1198 return crtc;
1199}
1200
1201void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
1202{
1203 struct drm_encoder *encoder = &intel_output->enc;
1204 struct drm_device *dev = encoder->dev;
1205 struct drm_crtc *crtc = encoder->crtc;
1206 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
1207 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1208
1209 if (intel_output->load_detect_temp) {
1210 encoder->crtc = NULL;
1211 intel_output->load_detect_temp = false;
1212 crtc->enabled = drm_helper_crtc_in_use(crtc);
1213 drm_helper_disable_unused_functions(dev);
1214 }
1215
1216 /* Switch crtc and output back off if necessary */
1217 if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
1218 if (encoder->crtc == crtc)
1219 encoder_funcs->dpms(encoder, dpms_mode);
1220 crtc_funcs->dpms(crtc, dpms_mode);
1221 }
1222}
1223
1224/* Returns the clock of the currently programmed mode of the given pipe. */
1225static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
1226{
1227 struct drm_i915_private *dev_priv = dev->dev_private;
1228 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1229 int pipe = intel_crtc->pipe;
1230 u32 dpll = I915_READ((pipe == 0) ? DPLL_A : DPLL_B);
1231 u32 fp;
1232 intel_clock_t clock;
1233
1234 if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
1235 fp = I915_READ((pipe == 0) ? FPA0 : FPB0);
1236 else
1237 fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
1238
1239 clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
1240 clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
1241 clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
1242 if (IS_I9XX(dev)) {
1243 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
1244 DPLL_FPA01_P1_POST_DIV_SHIFT);
1245
1246 switch (dpll & DPLL_MODE_MASK) {
1247 case DPLLB_MODE_DAC_SERIAL:
1248 clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ?
1249 5 : 10;
1250 break;
1251 case DPLLB_MODE_LVDS:
1252 clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ?
1253 7 : 14;
1254 break;
1255 default:
1256 DRM_DEBUG("Unknown DPLL mode %08x in programmed "
1257 "mode\n", (int)(dpll & DPLL_MODE_MASK));
1258 return 0;
1259 }
1260
1261 /* XXX: Handle the 100Mhz refclk */
1262 i9xx_clock(96000, &clock);
1263 } else {
1264 bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
1265
1266 if (is_lvds) {
1267 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
1268 DPLL_FPA01_P1_POST_DIV_SHIFT);
1269 clock.p2 = 14;
1270
1271 if ((dpll & PLL_REF_INPUT_MASK) ==
1272 PLLB_REF_INPUT_SPREADSPECTRUMIN) {
1273 /* XXX: might not be 66MHz */
1274 i8xx_clock(66000, &clock);
1275 } else
1276 i8xx_clock(48000, &clock);
1277 } else {
1278 if (dpll & PLL_P1_DIVIDE_BY_TWO)
1279 clock.p1 = 2;
1280 else {
1281 clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
1282 DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
1283 }
1284 if (dpll & PLL_P2_DIVIDE_BY_4)
1285 clock.p2 = 4;
1286 else
1287 clock.p2 = 2;
1288
1289 i8xx_clock(48000, &clock);
1290 }
1291 }
1292
1293 /* XXX: It would be nice to validate the clocks, but we can't reuse
1294 * i830PllIsValid() because it relies on the xf86_config connector
1295 * configuration being accurate, which it isn't necessarily.
1296 */
1297
1298 return clock.dot;
1299}
1300
1301/** Returns the currently programmed mode of the given pipe. */
1302struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
1303 struct drm_crtc *crtc)
1304{
1305 struct drm_i915_private *dev_priv = dev->dev_private;
1306 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1307 int pipe = intel_crtc->pipe;
1308 struct drm_display_mode *mode;
1309 int htot = I915_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
1310 int hsync = I915_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
1311 int vtot = I915_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
1312 int vsync = I915_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
1313
1314 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
1315 if (!mode)
1316 return NULL;
1317
1318 mode->clock = intel_crtc_clock_get(dev, crtc);
1319 mode->hdisplay = (htot & 0xffff) + 1;
1320 mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
1321 mode->hsync_start = (hsync & 0xffff) + 1;
1322 mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
1323 mode->vdisplay = (vtot & 0xffff) + 1;
1324 mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
1325 mode->vsync_start = (vsync & 0xffff) + 1;
1326 mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
1327
1328 drm_mode_set_name(mode);
1329 drm_mode_set_crtcinfo(mode, 0);
1330
1331 return mode;
1332}
1333
1334static void intel_crtc_destroy(struct drm_crtc *crtc)
1335{
1336 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1337
1338 drm_crtc_cleanup(crtc);
1339 kfree(intel_crtc);
1340}
1341
1342static const struct drm_crtc_helper_funcs intel_helper_funcs = {
1343 .dpms = intel_crtc_dpms,
1344 .mode_fixup = intel_crtc_mode_fixup,
1345 .mode_set = intel_crtc_mode_set,
1346 .mode_set_base = intel_pipe_set_base,
1347 .prepare = intel_crtc_prepare,
1348 .commit = intel_crtc_commit,
1349};
1350
1351static const struct drm_crtc_funcs intel_crtc_funcs = {
1352 .cursor_set = intel_crtc_cursor_set,
1353 .cursor_move = intel_crtc_cursor_move,
1354 .gamma_set = intel_crtc_gamma_set,
1355 .set_config = drm_crtc_helper_set_config,
1356 .destroy = intel_crtc_destroy,
1357};
1358
1359
1360static void intel_crtc_init(struct drm_device *dev, int pipe)
1361{
1362 struct intel_crtc *intel_crtc;
1363 int i;
1364
1365 intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
1366 if (intel_crtc == NULL)
1367 return;
1368
1369 drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs);
1370
1371 drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256);
1372 intel_crtc->pipe = pipe;
1373 for (i = 0; i < 256; i++) {
1374 intel_crtc->lut_r[i] = i;
1375 intel_crtc->lut_g[i] = i;
1376 intel_crtc->lut_b[i] = i;
1377 }
1378
1379 intel_crtc->cursor_addr = 0;
1380 intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
1381 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
1382
1383 intel_crtc->mode_set.crtc = &intel_crtc->base;
1384 intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1);
1385 intel_crtc->mode_set.num_connectors = 0;
1386
1387 if (i915_fbpercrtc) {
1388
1389
1390
1391 }
1392}
1393
1394struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
1395{
1396 struct drm_crtc *crtc = NULL;
1397
1398 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1399 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1400 if (intel_crtc->pipe == pipe)
1401 break;
1402 }
1403 return crtc;
1404}
1405
1406static int intel_connector_clones(struct drm_device *dev, int type_mask)
1407{
1408 int index_mask = 0;
1409 struct drm_connector *connector;
1410 int entry = 0;
1411
1412 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1413 struct intel_output *intel_output = to_intel_output(connector);
1414 if (type_mask & (1 << intel_output->type))
1415 index_mask |= (1 << entry);
1416 entry++;
1417 }
1418 return index_mask;
1419}
1420
1421
1422static void intel_setup_outputs(struct drm_device *dev)
1423{
1424 struct drm_connector *connector;
1425
1426 intel_crt_init(dev);
1427
1428 /* Set up integrated LVDS */
1429 if (IS_MOBILE(dev) && !IS_I830(dev))
1430 intel_lvds_init(dev);
1431
1432 if (IS_I9XX(dev)) {
1433 intel_sdvo_init(dev, SDVOB);
1434 intel_sdvo_init(dev, SDVOC);
1435 } else
1436 intel_dvo_init(dev);
1437
1438 if (IS_I9XX(dev) && !IS_I915G(dev))
1439 intel_tv_init(dev);
1440
1441 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1442 struct intel_output *intel_output = to_intel_output(connector);
1443 struct drm_encoder *encoder = &intel_output->enc;
1444 int crtc_mask = 0, clone_mask = 0;
1445
1446 /* valid crtcs */
1447 switch(intel_output->type) {
1448 case INTEL_OUTPUT_DVO:
1449 case INTEL_OUTPUT_SDVO:
1450 crtc_mask = ((1 << 0)|
1451 (1 << 1));
1452 clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
1453 (1 << INTEL_OUTPUT_DVO) |
1454 (1 << INTEL_OUTPUT_SDVO));
1455 break;
1456 case INTEL_OUTPUT_ANALOG:
1457 crtc_mask = ((1 << 0)|
1458 (1 << 1));
1459 clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
1460 (1 << INTEL_OUTPUT_DVO) |
1461 (1 << INTEL_OUTPUT_SDVO));
1462 break;
1463 case INTEL_OUTPUT_LVDS:
1464 crtc_mask = (1 << 1);
1465 clone_mask = (1 << INTEL_OUTPUT_LVDS);
1466 break;
1467 case INTEL_OUTPUT_TVOUT:
1468 crtc_mask = ((1 << 0) |
1469 (1 << 1));
1470 clone_mask = (1 << INTEL_OUTPUT_TVOUT);
1471 break;
1472 }
1473 encoder->possible_crtcs = crtc_mask;
1474 encoder->possible_clones = intel_connector_clones(dev, clone_mask);
1475 }
1476}
1477
1478static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
1479{
1480 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
1481 struct drm_device *dev = fb->dev;
1482
1483 if (fb->fbdev)
1484 intelfb_remove(dev, fb);
1485
1486 drm_framebuffer_cleanup(fb);
1487 mutex_lock(&dev->struct_mutex);
1488 drm_gem_object_unreference(intel_fb->obj);
1489 mutex_unlock(&dev->struct_mutex);
1490
1491 kfree(intel_fb);
1492}
1493
1494static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
1495 struct drm_file *file_priv,
1496 unsigned int *handle)
1497{
1498 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
1499 struct drm_gem_object *object = intel_fb->obj;
1500
1501 return drm_gem_handle_create(file_priv, object, handle);
1502}
1503
1504static const struct drm_framebuffer_funcs intel_fb_funcs = {
1505 .destroy = intel_user_framebuffer_destroy,
1506 .create_handle = intel_user_framebuffer_create_handle,
1507};
1508
1509int intel_framebuffer_create(struct drm_device *dev,
1510 struct drm_mode_fb_cmd *mode_cmd,
1511 struct drm_framebuffer **fb,
1512 struct drm_gem_object *obj)
1513{
1514 struct intel_framebuffer *intel_fb;
1515 int ret;
1516
1517 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
1518 if (!intel_fb)
1519 return -ENOMEM;
1520
1521 ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
1522 if (ret) {
1523 DRM_ERROR("framebuffer init failed %d\n", ret);
1524 return ret;
1525 }
1526
1527 drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
1528
1529 intel_fb->obj = obj;
1530
1531 *fb = &intel_fb->base;
1532
1533 return 0;
1534}
1535
1536
1537static struct drm_framebuffer *
1538intel_user_framebuffer_create(struct drm_device *dev,
1539 struct drm_file *filp,
1540 struct drm_mode_fb_cmd *mode_cmd)
1541{
1542 struct drm_gem_object *obj;
1543 struct drm_framebuffer *fb;
1544 int ret;
1545
1546 obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle);
1547 if (!obj)
1548 return NULL;
1549
1550 ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj);
1551 if (ret) {
1552 drm_gem_object_unreference(obj);
1553 return NULL;
1554 }
1555
1556 return fb;
1557}
1558
1559static const struct drm_mode_config_funcs intel_mode_funcs = {
1560 .fb_create = intel_user_framebuffer_create,
1561 .fb_changed = intelfb_probe,
1562};
1563
1564void intel_modeset_init(struct drm_device *dev)
1565{
1566 int num_pipe;
1567 int i;
1568
1569 drm_mode_config_init(dev);
1570
1571 dev->mode_config.min_width = 0;
1572 dev->mode_config.min_height = 0;
1573
1574 dev->mode_config.funcs = (void *)&intel_mode_funcs;
1575
1576 if (IS_I965G(dev)) {
1577 dev->mode_config.max_width = 8192;
1578 dev->mode_config.max_height = 8192;
1579 } else {
1580 dev->mode_config.max_width = 2048;
1581 dev->mode_config.max_height = 2048;
1582 }
1583
1584 /* set memory base */
1585 if (IS_I9XX(dev))
1586 dev->mode_config.fb_base = pci_resource_start(dev->pdev, 2);
1587 else
1588 dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0);
1589
1590 if (IS_MOBILE(dev) || IS_I9XX(dev))
1591 num_pipe = 2;
1592 else
1593 num_pipe = 1;
1594 DRM_DEBUG("%d display pipe%s available.\n",
1595 num_pipe, num_pipe > 1 ? "s" : "");
1596
1597 for (i = 0; i < num_pipe; i++) {
1598 intel_crtc_init(dev, i);
1599 }
1600
1601 intel_setup_outputs(dev);
1602}
1603
1604void intel_modeset_cleanup(struct drm_device *dev)
1605{
1606 drm_mode_config_cleanup(dev);
1607}
1608
1609
1610/* current intel driver doesn't take advantage of encoders
1611 always give back the encoder for the connector
1612*/
1613struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
1614{
1615 struct intel_output *intel_output = to_intel_output(connector);
1616
1617 return &intel_output->enc;
1618}
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..8b8d6e65cd3f
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -0,0 +1,495 @@
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
40static struct intel_dvo_device intel_dvo_devices[] = {
41 {
42 .type = INTEL_DVO_CHIP_TMDS,
43 .name = "sil164",
44 .dvo_reg = DVOC,
45 .slave_addr = SIL164_ADDR,
46 .dev_ops = &sil164_ops,
47 },
48 {
49 .type = INTEL_DVO_CHIP_TMDS,
50 .name = "ch7xxx",
51 .dvo_reg = DVOC,
52 .slave_addr = CH7xxx_ADDR,
53 .dev_ops = &ch7xxx_ops,
54 },
55 {
56 .type = INTEL_DVO_CHIP_LVDS,
57 .name = "ivch",
58 .dvo_reg = DVOA,
59 .slave_addr = 0x02, /* Might also be 0x44, 0x84, 0xc4 */
60 .dev_ops = &ivch_ops,
61 },
62 {
63 .type = INTEL_DVO_CHIP_TMDS,
64 .name = "tfp410",
65 .dvo_reg = DVOC,
66 .slave_addr = TFP410_ADDR,
67 .dev_ops = &tfp410_ops,
68 },
69 {
70 .type = INTEL_DVO_CHIP_LVDS,
71 .name = "ch7017",
72 .dvo_reg = DVOC,
73 .slave_addr = 0x75,
74 .gpio = GPIOE,
75 .dev_ops = &ch7017_ops,
76 }
77};
78
79static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
80{
81 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
82 struct intel_output *intel_output = enc_to_intel_output(encoder);
83 struct intel_dvo_device *dvo = intel_output->dev_priv;
84 u32 dvo_reg = dvo->dvo_reg;
85 u32 temp = I915_READ(dvo_reg);
86
87 if (mode == DRM_MODE_DPMS_ON) {
88 I915_WRITE(dvo_reg, temp | DVO_ENABLE);
89 I915_READ(dvo_reg);
90 dvo->dev_ops->dpms(dvo, mode);
91 } else {
92 dvo->dev_ops->dpms(dvo, mode);
93 I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
94 I915_READ(dvo_reg);
95 }
96}
97
98static void intel_dvo_save(struct drm_connector *connector)
99{
100 struct drm_i915_private *dev_priv = connector->dev->dev_private;
101 struct intel_output *intel_output = to_intel_output(connector);
102 struct intel_dvo_device *dvo = intel_output->dev_priv;
103
104 /* Each output should probably just save the registers it touches,
105 * but for now, use more overkill.
106 */
107 dev_priv->saveDVOA = I915_READ(DVOA);
108 dev_priv->saveDVOB = I915_READ(DVOB);
109 dev_priv->saveDVOC = I915_READ(DVOC);
110
111 dvo->dev_ops->save(dvo);
112}
113
114static void intel_dvo_restore(struct drm_connector *connector)
115{
116 struct drm_i915_private *dev_priv = connector->dev->dev_private;
117 struct intel_output *intel_output = to_intel_output(connector);
118 struct intel_dvo_device *dvo = intel_output->dev_priv;
119
120 dvo->dev_ops->restore(dvo);
121
122 I915_WRITE(DVOA, dev_priv->saveDVOA);
123 I915_WRITE(DVOB, dev_priv->saveDVOB);
124 I915_WRITE(DVOC, dev_priv->saveDVOC);
125}
126
127static int intel_dvo_mode_valid(struct drm_connector *connector,
128 struct drm_display_mode *mode)
129{
130 struct intel_output *intel_output = to_intel_output(connector);
131 struct intel_dvo_device *dvo = intel_output->dev_priv;
132
133 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
134 return MODE_NO_DBLESCAN;
135
136 /* XXX: Validate clock range */
137
138 if (dvo->panel_fixed_mode) {
139 if (mode->hdisplay > dvo->panel_fixed_mode->hdisplay)
140 return MODE_PANEL;
141 if (mode->vdisplay > dvo->panel_fixed_mode->vdisplay)
142 return MODE_PANEL;
143 }
144
145 return dvo->dev_ops->mode_valid(dvo, mode);
146}
147
148static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
149 struct drm_display_mode *mode,
150 struct drm_display_mode *adjusted_mode)
151{
152 struct intel_output *intel_output = enc_to_intel_output(encoder);
153 struct intel_dvo_device *dvo = intel_output->dev_priv;
154
155 /* If we have timings from the BIOS for the panel, put them in
156 * to the adjusted mode. The CRTC will be set up for this mode,
157 * with the panel scaling set up to source from the H/VDisplay
158 * of the original mode.
159 */
160 if (dvo->panel_fixed_mode != NULL) {
161#define C(x) adjusted_mode->x = dvo->panel_fixed_mode->x
162 C(hdisplay);
163 C(hsync_start);
164 C(hsync_end);
165 C(htotal);
166 C(vdisplay);
167 C(vsync_start);
168 C(vsync_end);
169 C(vtotal);
170 C(clock);
171 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
172#undef C
173 }
174
175 if (dvo->dev_ops->mode_fixup)
176 return dvo->dev_ops->mode_fixup(dvo, mode, adjusted_mode);
177
178 return true;
179}
180
181static void intel_dvo_mode_set(struct drm_encoder *encoder,
182 struct drm_display_mode *mode,
183 struct drm_display_mode *adjusted_mode)
184{
185 struct drm_device *dev = encoder->dev;
186 struct drm_i915_private *dev_priv = dev->dev_private;
187 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
188 struct intel_output *intel_output = enc_to_intel_output(encoder);
189 struct intel_dvo_device *dvo = intel_output->dev_priv;
190 int pipe = intel_crtc->pipe;
191 u32 dvo_val;
192 u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
193 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
194
195 switch (dvo_reg) {
196 case DVOA:
197 default:
198 dvo_srcdim_reg = DVOA_SRCDIM;
199 break;
200 case DVOB:
201 dvo_srcdim_reg = DVOB_SRCDIM;
202 break;
203 case DVOC:
204 dvo_srcdim_reg = DVOC_SRCDIM;
205 break;
206 }
207
208 dvo->dev_ops->mode_set(dvo, mode, adjusted_mode);
209
210 /* Save the data order, since I don't know what it should be set to. */
211 dvo_val = I915_READ(dvo_reg) &
212 (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
213 dvo_val |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE |
214 DVO_BLANK_ACTIVE_HIGH;
215
216 if (pipe == 1)
217 dvo_val |= DVO_PIPE_B_SELECT;
218 dvo_val |= DVO_PIPE_STALL;
219 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
220 dvo_val |= DVO_HSYNC_ACTIVE_HIGH;
221 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
222 dvo_val |= DVO_VSYNC_ACTIVE_HIGH;
223
224 I915_WRITE(dpll_reg, I915_READ(dpll_reg) | DPLL_DVO_HIGH_SPEED);
225
226 /*I915_WRITE(DVOB_SRCDIM,
227 (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
228 (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/
229 I915_WRITE(dvo_srcdim_reg,
230 (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
231 (adjusted_mode->vdisplay << DVO_SRCDIM_VERTICAL_SHIFT));
232 /*I915_WRITE(DVOB, dvo_val);*/
233 I915_WRITE(dvo_reg, dvo_val);
234}
235
236/**
237 * Detect the output connection on our DVO device.
238 *
239 * Unimplemented.
240 */
241static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
242{
243 struct intel_output *intel_output = to_intel_output(connector);
244 struct intel_dvo_device *dvo = intel_output->dev_priv;
245
246 return dvo->dev_ops->detect(dvo);
247}
248
249static int intel_dvo_get_modes(struct drm_connector *connector)
250{
251 struct intel_output *intel_output = to_intel_output(connector);
252 struct intel_dvo_device *dvo = intel_output->dev_priv;
253
254 /* We should probably have an i2c driver get_modes function for those
255 * devices which will have a fixed set of modes determined by the chip
256 * (TV-out, for example), but for now with just TMDS and LVDS,
257 * that's not the case.
258 */
259 intel_ddc_get_modes(intel_output);
260 if (!list_empty(&connector->probed_modes))
261 return 1;
262
263
264 if (dvo->panel_fixed_mode != NULL) {
265 struct drm_display_mode *mode;
266 mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode);
267 if (mode) {
268 drm_mode_probed_add(connector, mode);
269 return 1;
270 }
271 }
272 return 0;
273}
274
275static void intel_dvo_destroy (struct drm_connector *connector)
276{
277 struct intel_output *intel_output = to_intel_output(connector);
278 struct intel_dvo_device *dvo = intel_output->dev_priv;
279
280 if (dvo) {
281 if (dvo->dev_ops->destroy)
282 dvo->dev_ops->destroy(dvo);
283 if (dvo->panel_fixed_mode)
284 kfree(dvo->panel_fixed_mode);
285 /* no need, in i830_dvoices[] now */
286 //kfree(dvo);
287 }
288 if (intel_output->i2c_bus)
289 intel_i2c_destroy(intel_output->i2c_bus);
290 if (intel_output->ddc_bus)
291 intel_i2c_destroy(intel_output->ddc_bus);
292 drm_sysfs_connector_remove(connector);
293 drm_connector_cleanup(connector);
294 kfree(intel_output);
295}
296
297#ifdef RANDR_GET_CRTC_INTERFACE
298static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
299{
300 struct drm_device *dev = connector->dev;
301 struct drm_i915_private *dev_priv = dev->dev_private;
302 struct intel_output *intel_output = to_intel_output(connector);
303 struct intel_dvo_device *dvo = intel_output->dev_priv;
304 int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
305
306 return intel_pipe_to_crtc(pScrn, pipe);
307}
308#endif
309
310static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
311 .dpms = intel_dvo_dpms,
312 .mode_fixup = intel_dvo_mode_fixup,
313 .prepare = intel_encoder_prepare,
314 .mode_set = intel_dvo_mode_set,
315 .commit = intel_encoder_commit,
316};
317
318static const struct drm_connector_funcs intel_dvo_connector_funcs = {
319 .save = intel_dvo_save,
320 .restore = intel_dvo_restore,
321 .detect = intel_dvo_detect,
322 .destroy = intel_dvo_destroy,
323 .fill_modes = drm_helper_probe_single_connector_modes,
324};
325
326static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
327 .mode_valid = intel_dvo_mode_valid,
328 .get_modes = intel_dvo_get_modes,
329 .best_encoder = intel_best_encoder,
330};
331
332static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
333{
334 drm_encoder_cleanup(encoder);
335}
336
337static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
338 .destroy = intel_dvo_enc_destroy,
339};
340
341
342/**
343 * Attempts to get a fixed panel timing for LVDS (currently only the i830).
344 *
345 * Other chips with DVO LVDS will need to extend this to deal with the LVDS
346 * chip being on DVOB/C and having multiple pipes.
347 */
348static struct drm_display_mode *
349intel_dvo_get_current_mode (struct drm_connector *connector)
350{
351 struct drm_device *dev = connector->dev;
352 struct drm_i915_private *dev_priv = dev->dev_private;
353 struct intel_output *intel_output = to_intel_output(connector);
354 struct intel_dvo_device *dvo = intel_output->dev_priv;
355 uint32_t dvo_reg = dvo->dvo_reg;
356 uint32_t dvo_val = I915_READ(dvo_reg);
357 struct drm_display_mode *mode = NULL;
358
359 /* If the DVO port is active, that'll be the LVDS, so we can pull out
360 * its timings to get how the BIOS set up the panel.
361 */
362 if (dvo_val & DVO_ENABLE) {
363 struct drm_crtc *crtc;
364 int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0;
365
366 crtc = intel_get_crtc_from_pipe(dev, pipe);
367 if (crtc) {
368 mode = intel_crtc_mode_get(dev, crtc);
369
370 if (mode) {
371 mode->type |= DRM_MODE_TYPE_PREFERRED;
372 if (dvo_val & DVO_HSYNC_ACTIVE_HIGH)
373 mode->flags |= DRM_MODE_FLAG_PHSYNC;
374 if (dvo_val & DVO_VSYNC_ACTIVE_HIGH)
375 mode->flags |= DRM_MODE_FLAG_PVSYNC;
376 }
377 }
378 }
379 return mode;
380}
381
382void intel_dvo_init(struct drm_device *dev)
383{
384 struct intel_output *intel_output;
385 struct intel_dvo_device *dvo;
386 struct intel_i2c_chan *i2cbus = NULL;
387 int ret = 0;
388 int i;
389 int gpio_inited = 0;
390 int encoder_type = DRM_MODE_ENCODER_NONE;
391 intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
392 if (!intel_output)
393 return;
394
395 /* Set up the DDC bus */
396 intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
397 if (!intel_output->ddc_bus)
398 goto free_intel;
399
400 /* Now, try to find a controller */
401 for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
402 struct drm_connector *connector = &intel_output->base;
403 int gpio;
404
405 dvo = &intel_dvo_devices[i];
406
407 /* Allow the I2C driver info to specify the GPIO to be used in
408 * special cases, but otherwise default to what's defined
409 * in the spec.
410 */
411 if (dvo->gpio != 0)
412 gpio = dvo->gpio;
413 else if (dvo->type == INTEL_DVO_CHIP_LVDS)
414 gpio = GPIOB;
415 else
416 gpio = GPIOE;
417
418 /* Set up the I2C bus necessary for the chip we're probing.
419 * It appears that everything is on GPIOE except for panels
420 * on i830 laptops, which are on GPIOB (DVOA).
421 */
422 if (gpio_inited != gpio) {
423 if (i2cbus != NULL)
424 intel_i2c_destroy(i2cbus);
425 if (!(i2cbus = intel_i2c_create(dev, gpio,
426 gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) {
427 continue;
428 }
429 gpio_inited = gpio;
430 }
431
432 if (dvo->dev_ops!= NULL)
433 ret = dvo->dev_ops->init(dvo, i2cbus);
434 else
435 ret = false;
436
437 if (!ret)
438 continue;
439
440 intel_output->type = INTEL_OUTPUT_DVO;
441 switch (dvo->type) {
442 case INTEL_DVO_CHIP_TMDS:
443 drm_connector_init(dev, connector,
444 &intel_dvo_connector_funcs,
445 DRM_MODE_CONNECTOR_DVII);
446 encoder_type = DRM_MODE_ENCODER_TMDS;
447 break;
448 case INTEL_DVO_CHIP_LVDS:
449 drm_connector_init(dev, connector,
450 &intel_dvo_connector_funcs,
451 DRM_MODE_CONNECTOR_LVDS);
452 encoder_type = DRM_MODE_ENCODER_LVDS;
453 break;
454 }
455
456 drm_connector_helper_add(connector,
457 &intel_dvo_connector_helper_funcs);
458 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
459 connector->interlace_allowed = false;
460 connector->doublescan_allowed = false;
461
462 intel_output->dev_priv = dvo;
463 intel_output->i2c_bus = i2cbus;
464
465 drm_encoder_init(dev, &intel_output->enc,
466 &intel_dvo_enc_funcs, encoder_type);
467 drm_encoder_helper_add(&intel_output->enc,
468 &intel_dvo_helper_funcs);
469
470 drm_mode_connector_attach_encoder(&intel_output->base,
471 &intel_output->enc);
472 if (dvo->type == INTEL_DVO_CHIP_LVDS) {
473 /* For our LVDS chipsets, we should hopefully be able
474 * to dig the fixed panel mode out of the BIOS data.
475 * However, it's in a different format from the BIOS
476 * data on chipsets with integrated LVDS (stored in AIM
477 * headers, likely), so for now, just get the current
478 * mode being output through DVO.
479 */
480 dvo->panel_fixed_mode =
481 intel_dvo_get_current_mode(connector);
482 dvo->panel_wants_dither = true;
483 }
484
485 drm_sysfs_connector_add(connector);
486 return;
487 }
488
489 intel_i2c_destroy(intel_output->ddc_bus);
490 /* Didn't find a chip, so tear down. */
491 if (i2cbus != NULL)
492 intel_i2c_destroy(i2cbus);
493free_intel:
494 kfree(intel_output);
495}
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
new file mode 100644
index 000000000000..afd1217b8a02
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -0,0 +1,925 @@
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
341static int 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
417static int 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}
425
426static struct notifier_block paniced = {
427 .notifier_call = intelfb_panic,
428};
429
430static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
431 uint32_t fb_height, uint32_t surface_width,
432 uint32_t surface_height,
433 struct intel_framebuffer **intel_fb_p)
434{
435 struct fb_info *info;
436 struct intelfb_par *par;
437 struct drm_framebuffer *fb;
438 struct intel_framebuffer *intel_fb;
439 struct drm_mode_fb_cmd mode_cmd;
440 struct drm_gem_object *fbo = NULL;
441 struct drm_i915_gem_object *obj_priv;
442 struct device *device = &dev->pdev->dev;
443 int size, ret, mmio_bar = IS_I9XX(dev) ? 0 : 1;
444
445 mode_cmd.width = surface_width;
446 mode_cmd.height = surface_height;
447
448 mode_cmd.bpp = 32;
449 mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64);
450 mode_cmd.depth = 24;
451
452 size = mode_cmd.pitch * mode_cmd.height;
453 size = ALIGN(size, PAGE_SIZE);
454 fbo = drm_gem_object_alloc(dev, size);
455 if (!fbo) {
456 printk(KERN_ERR "failed to allocate framebuffer\n");
457 ret = -ENOMEM;
458 goto out;
459 }
460 obj_priv = fbo->driver_private;
461
462 mutex_lock(&dev->struct_mutex);
463
464 ret = i915_gem_object_pin(fbo, PAGE_SIZE);
465 if (ret) {
466 DRM_ERROR("failed to pin fb: %d\n", ret);
467 goto out_unref;
468 }
469
470 /* Flush everything out, we'll be doing GTT only from now on */
471 i915_gem_object_set_to_gtt_domain(fbo, 1);
472
473 ret = intel_framebuffer_create(dev, &mode_cmd, &fb, fbo);
474 if (ret) {
475 DRM_ERROR("failed to allocate fb.\n");
476 goto out_unref;
477 }
478
479 list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
480
481 intel_fb = to_intel_framebuffer(fb);
482 *intel_fb_p = intel_fb;
483
484 info = framebuffer_alloc(sizeof(struct intelfb_par), device);
485 if (!info) {
486 ret = -ENOMEM;
487 goto out_unref;
488 }
489
490 par = info->par;
491
492 strcpy(info->fix.id, "inteldrmfb");
493 info->fix.type = FB_TYPE_PACKED_PIXELS;
494 info->fix.visual = FB_VISUAL_TRUECOLOR;
495 info->fix.type_aux = 0;
496 info->fix.xpanstep = 1; /* doing it in hw */
497 info->fix.ypanstep = 1; /* doing it in hw */
498 info->fix.ywrapstep = 0;
499 info->fix.accel = FB_ACCEL_I830;
500 info->fix.type_aux = 0;
501
502 info->flags = FBINFO_DEFAULT;
503
504 info->fbops = &intelfb_ops;
505
506 info->fix.line_length = fb->pitch;
507 info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset;
508 info->fix.smem_len = size;
509
510 info->flags = FBINFO_DEFAULT;
511
512 info->screen_base = ioremap_wc(dev->agp->base + obj_priv->gtt_offset,
513 size);
514 if (!info->screen_base) {
515 ret = -ENOSPC;
516 goto out_unref;
517 }
518 info->screen_size = size;
519
520// memset(info->screen_base, 0, size);
521
522 info->pseudo_palette = fb->pseudo_palette;
523 info->var.xres_virtual = fb->width;
524 info->var.yres_virtual = fb->height;
525 info->var.bits_per_pixel = fb->bits_per_pixel;
526 info->var.xoffset = 0;
527 info->var.yoffset = 0;
528 info->var.activate = FB_ACTIVATE_NOW;
529 info->var.height = -1;
530 info->var.width = -1;
531
532 info->var.xres = fb_width;
533 info->var.yres = fb_height;
534
535 /* FIXME: we really shouldn't expose mmio space at all */
536 info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar);
537 info->fix.mmio_len = pci_resource_len(dev->pdev, mmio_bar);
538
539 info->pixmap.size = 64*1024;
540 info->pixmap.buf_align = 8;
541 info->pixmap.access_align = 32;
542 info->pixmap.flags = FB_PIXMAP_SYSTEM;
543 info->pixmap.scan_align = 1;
544
545 switch(fb->depth) {
546 case 8:
547 info->var.red.offset = 0;
548 info->var.green.offset = 0;
549 info->var.blue.offset = 0;
550 info->var.red.length = 8; /* 8bit DAC */
551 info->var.green.length = 8;
552 info->var.blue.length = 8;
553 info->var.transp.offset = 0;
554 info->var.transp.length = 0;
555 break;
556 case 15:
557 info->var.red.offset = 10;
558 info->var.green.offset = 5;
559 info->var.blue.offset = 0;
560 info->var.red.length = 5;
561 info->var.green.length = 5;
562 info->var.blue.length = 5;
563 info->var.transp.offset = 15;
564 info->var.transp.length = 1;
565 break;
566 case 16:
567 info->var.red.offset = 11;
568 info->var.green.offset = 5;
569 info->var.blue.offset = 0;
570 info->var.red.length = 5;
571 info->var.green.length = 6;
572 info->var.blue.length = 5;
573 info->var.transp.offset = 0;
574 break;
575 case 24:
576 info->var.red.offset = 16;
577 info->var.green.offset = 8;
578 info->var.blue.offset = 0;
579 info->var.red.length = 8;
580 info->var.green.length = 8;
581 info->var.blue.length = 8;
582 info->var.transp.offset = 0;
583 info->var.transp.length = 0;
584 break;
585 case 32:
586 info->var.red.offset = 16;
587 info->var.green.offset = 8;
588 info->var.blue.offset = 0;
589 info->var.red.length = 8;
590 info->var.green.length = 8;
591 info->var.blue.length = 8;
592 info->var.transp.offset = 24;
593 info->var.transp.length = 8;
594 break;
595 default:
596 break;
597 }
598
599 fb->fbdev = info;
600
601 par->intel_fb = intel_fb;
602 par->dev = dev;
603
604 /* To allow resizeing without swapping buffers */
605 printk("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width,
606 intel_fb->base.height, obj_priv->gtt_offset, fbo);
607
608 mutex_unlock(&dev->struct_mutex);
609 return 0;
610
611out_unref:
612 drm_gem_object_unreference(fbo);
613 mutex_unlock(&dev->struct_mutex);
614out:
615 return ret;
616}
617
618static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc *crtc)
619{
620 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
621 struct intel_framebuffer *intel_fb;
622 struct drm_framebuffer *fb;
623 struct drm_connector *connector;
624 struct fb_info *info;
625 struct intelfb_par *par;
626 struct drm_mode_set *modeset;
627 unsigned int width, height;
628 int new_fb = 0;
629 int ret, i, conn_count;
630
631 if (!drm_helper_crtc_in_use(crtc))
632 return 0;
633
634 if (!crtc->desired_mode)
635 return 0;
636
637 width = crtc->desired_mode->hdisplay;
638 height = crtc->desired_mode->vdisplay;
639
640 /* is there an fb bound to this crtc already */
641 if (!intel_crtc->mode_set.fb) {
642 ret = intelfb_create(dev, width, height, width, height, &intel_fb);
643 if (ret)
644 return -EINVAL;
645 new_fb = 1;
646 } else {
647 fb = intel_crtc->mode_set.fb;
648 intel_fb = to_intel_framebuffer(fb);
649 if ((intel_fb->base.width < width) || (intel_fb->base.height < height))
650 return -EINVAL;
651 }
652
653 info = intel_fb->base.fbdev;
654 par = info->par;
655
656 modeset = &intel_crtc->mode_set;
657 modeset->fb = &intel_fb->base;
658 conn_count = 0;
659 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
660 if (connector->encoder)
661 if (connector->encoder->crtc == modeset->crtc) {
662 modeset->connectors[conn_count] = connector;
663 conn_count++;
664 if (conn_count > INTELFB_CONN_LIMIT)
665 BUG();
666 }
667 }
668
669 for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
670 modeset->connectors[i] = NULL;
671
672 par->crtc_ids[0] = crtc->base.id;
673
674 modeset->num_connectors = conn_count;
675 if (modeset->mode != modeset->crtc->desired_mode)
676 modeset->mode = modeset->crtc->desired_mode;
677
678 par->crtc_count = 1;
679
680 if (new_fb) {
681 info->var.pixclock = -1;
682 if (register_framebuffer(info) < 0)
683 return -EINVAL;
684 } else
685 intelfb_set_par(info);
686
687 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
688 info->fix.id);
689
690 /* Switch back to kernel console on panic */
691 kernelfb_mode = *modeset;
692 atomic_notifier_chain_register(&panic_notifier_list, &paniced);
693 printk(KERN_INFO "registered panic notifier\n");
694
695 return 0;
696}
697
698static int intelfb_multi_fb_probe(struct drm_device *dev)
699{
700
701 struct drm_crtc *crtc;
702 int ret = 0;
703
704 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
705 ret = intelfb_multi_fb_probe_crtc(dev, crtc);
706 if (ret)
707 return ret;
708 }
709 return ret;
710}
711
712static int intelfb_single_fb_probe(struct drm_device *dev)
713{
714 struct drm_crtc *crtc;
715 struct drm_connector *connector;
716 unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
717 unsigned int surface_width = 0, surface_height = 0;
718 int new_fb = 0;
719 int crtc_count = 0;
720 int ret, i, conn_count = 0;
721 struct intel_framebuffer *intel_fb;
722 struct fb_info *info;
723 struct intelfb_par *par;
724 struct drm_mode_set *modeset = NULL;
725
726 DRM_DEBUG("\n");
727
728 /* Get a count of crtcs now in use and new min/maxes width/heights */
729 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
730 if (!drm_helper_crtc_in_use(crtc))
731 continue;
732
733 crtc_count++;
734 if (!crtc->desired_mode)
735 continue;
736
737 /* Smallest mode determines console size... */
738 if (crtc->desired_mode->hdisplay < fb_width)
739 fb_width = crtc->desired_mode->hdisplay;
740
741 if (crtc->desired_mode->vdisplay < fb_height)
742 fb_height = crtc->desired_mode->vdisplay;
743
744 /* ... but largest for memory allocation dimensions */
745 if (crtc->desired_mode->hdisplay > surface_width)
746 surface_width = crtc->desired_mode->hdisplay;
747
748 if (crtc->desired_mode->vdisplay > surface_height)
749 surface_height = crtc->desired_mode->vdisplay;
750 }
751
752 if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
753 /* hmm everyone went away - assume VGA cable just fell out
754 and will come back later. */
755 DRM_DEBUG("no CRTCs available?\n");
756 return 0;
757 }
758
759//fail
760 /* Find the fb for our new config */
761 if (list_empty(&dev->mode_config.fb_kernel_list)) {
762 DRM_DEBUG("creating new fb (console size %dx%d, "
763 "buffer size %dx%d)\n", fb_width, fb_height,
764 surface_width, surface_height);
765 ret = intelfb_create(dev, fb_width, fb_height, surface_width,
766 surface_height, &intel_fb);
767 if (ret)
768 return -EINVAL;
769 new_fb = 1;
770 } else {
771 struct drm_framebuffer *fb;
772
773 fb = list_first_entry(&dev->mode_config.fb_kernel_list,
774 struct drm_framebuffer, filp_head);
775 intel_fb = to_intel_framebuffer(fb);
776
777 /* if someone hotplugs something bigger than we have already
778 * allocated, we are pwned. As really we can't resize an
779 * fbdev that is in the wild currently due to fbdev not really
780 * being designed for the lower layers moving stuff around
781 * under it.
782 * - so in the grand style of things - punt.
783 */
784 if ((fb->width < surface_width) ||
785 (fb->height < surface_height)) {
786 DRM_ERROR("fb not large enough for console\n");
787 return -EINVAL;
788 }
789 }
790// fail
791
792 info = intel_fb->base.fbdev;
793 par = info->par;
794
795 crtc_count = 0;
796 /*
797 * For each CRTC, set up the connector list for the CRTC's mode
798 * set configuration.
799 */
800 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
801 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
802
803 modeset = &intel_crtc->mode_set;
804 modeset->fb = &intel_fb->base;
805 conn_count = 0;
806 list_for_each_entry(connector, &dev->mode_config.connector_list,
807 head) {
808 if (!connector->encoder)
809 continue;
810
811 if(connector->encoder->crtc == modeset->crtc) {
812 modeset->connectors[conn_count++] = connector;
813 if (conn_count > INTELFB_CONN_LIMIT)
814 BUG();
815 }
816 }
817
818 /* Zero out remaining connector pointers */
819 for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
820 modeset->connectors[i] = NULL;
821
822 par->crtc_ids[crtc_count++] = crtc->base.id;
823
824 modeset->num_connectors = conn_count;
825 if (modeset->mode != modeset->crtc->desired_mode)
826 modeset->mode = modeset->crtc->desired_mode;
827 }
828 par->crtc_count = crtc_count;
829
830 if (new_fb) {
831 info->var.pixclock = -1;
832 if (register_framebuffer(info) < 0)
833 return -EINVAL;
834 } else
835 intelfb_set_par(info);
836
837 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
838 info->fix.id);
839
840 /* Switch back to kernel console on panic */
841 kernelfb_mode = *modeset;
842 atomic_notifier_chain_register(&panic_notifier_list, &paniced);
843 printk(KERN_INFO "registered panic notifier\n");
844
845 return 0;
846}
847
848/**
849 * intelfb_restore - restore the framebuffer console (kernel) config
850 *
851 * Restore's the kernel's fbcon mode, used for lastclose & panic paths.
852 */
853void intelfb_restore(void)
854{
855 drm_crtc_helper_set_config(&kernelfb_mode);
856}
857
858static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3)
859{
860 intelfb_restore();
861}
862
863static struct sysrq_key_op sysrq_intelfb_restore_op = {
864 .handler = intelfb_sysrq,
865 .help_msg = "force fb",
866 .action_msg = "force restore of fb console",
867};
868
869int intelfb_probe(struct drm_device *dev)
870{
871 int ret;
872
873 DRM_DEBUG("\n");
874
875 /* something has changed in the lower levels of hell - deal with it
876 here */
877
878 /* two modes : a) 1 fb to rule all crtcs.
879 b) one fb per crtc.
880 two actions 1) new connected device
881 2) device removed.
882 case a/1 : if the fb surface isn't big enough - resize the surface fb.
883 if the fb size isn't big enough - resize fb into surface.
884 if everything big enough configure the new crtc/etc.
885 case a/2 : undo the configuration
886 possibly resize down the fb to fit the new configuration.
887 case b/1 : see if it is on a new crtc - setup a new fb and add it.
888 case b/2 : teardown the new fb.
889 */
890
891 /* mode a first */
892 /* search for an fb */
893 if (i915_fbpercrtc == 1) {
894 ret = intelfb_multi_fb_probe(dev);
895 } else {
896 ret = intelfb_single_fb_probe(dev);
897 }
898
899 register_sysrq_key('g', &sysrq_intelfb_restore_op);
900
901 return ret;
902}
903EXPORT_SYMBOL(intelfb_probe);
904
905int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
906{
907 struct fb_info *info;
908
909 if (!fb)
910 return -EINVAL;
911
912 info = fb->fbdev;
913
914 if (info) {
915 unregister_framebuffer(info);
916 iounmap(info->screen_base);
917 framebuffer_release(info);
918 }
919
920 atomic_notifier_chain_unregister(&panic_notifier_list, &paniced);
921 memset(&kernelfb_mode, 0, sizeof(struct drm_mode_set));
922 return 0;
923}
924EXPORT_SYMBOL(intelfb_remove);
925MODULE_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..fbbaa4f414a0
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -0,0 +1,1128 @@
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 */
62static void 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
299static int 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 */
314static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
315 u8 target)
316{
317 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
318}
319
320static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
321{
322 struct intel_sdvo_set_target_input_args targets = {0};
323 u8 status;
324
325 if (target_0 && target_1)
326 return SDVO_CMD_STATUS_NOTSUPP;
327
328 if (target_1)
329 targets.target_1 = 1;
330
331 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
332 sizeof(targets));
333
334 status = intel_sdvo_read_response(intel_output, NULL, 0);
335
336 return (status == SDVO_CMD_STATUS_SUCCESS);
337}
338
339/**
340 * Return whether each input is trained.
341 *
342 * This function is making an assumption about the layout of the response,
343 * which should be checked against the docs.
344 */
345static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
346{
347 struct intel_sdvo_get_trained_inputs_response response;
348 u8 status;
349
350 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
351 status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
352 if (status != SDVO_CMD_STATUS_SUCCESS)
353 return false;
354
355 *input_1 = response.input0_trained;
356 *input_2 = response.input1_trained;
357 return true;
358}
359
360static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
361 u16 *outputs)
362{
363 u8 status;
364
365 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
366 status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
367
368 return (status == SDVO_CMD_STATUS_SUCCESS);
369}
370
371static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
372 u16 outputs)
373{
374 u8 status;
375
376 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
377 sizeof(outputs));
378 status = intel_sdvo_read_response(intel_output, NULL, 0);
379 return (status == SDVO_CMD_STATUS_SUCCESS);
380}
381
382static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
383 int mode)
384{
385 u8 status, state = SDVO_ENCODER_STATE_ON;
386
387 switch (mode) {
388 case DRM_MODE_DPMS_ON:
389 state = SDVO_ENCODER_STATE_ON;
390 break;
391 case DRM_MODE_DPMS_STANDBY:
392 state = SDVO_ENCODER_STATE_STANDBY;
393 break;
394 case DRM_MODE_DPMS_SUSPEND:
395 state = SDVO_ENCODER_STATE_SUSPEND;
396 break;
397 case DRM_MODE_DPMS_OFF:
398 state = SDVO_ENCODER_STATE_OFF;
399 break;
400 }
401
402 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
403 sizeof(state));
404 status = intel_sdvo_read_response(intel_output, NULL, 0);
405
406 return (status == SDVO_CMD_STATUS_SUCCESS);
407}
408
409static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
410 int *clock_min,
411 int *clock_max)
412{
413 struct intel_sdvo_pixel_clock_range clocks;
414 u8 status;
415
416 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
417 NULL, 0);
418
419 status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
420
421 if (status != SDVO_CMD_STATUS_SUCCESS)
422 return false;
423
424 /* Convert the values from units of 10 kHz to kHz. */
425 *clock_min = clocks.min * 10;
426 *clock_max = clocks.max * 10;
427
428 return true;
429}
430
431static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
432 u16 outputs)
433{
434 u8 status;
435
436 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
437 sizeof(outputs));
438
439 status = intel_sdvo_read_response(intel_output, NULL, 0);
440 return (status == SDVO_CMD_STATUS_SUCCESS);
441}
442
443static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
444 struct intel_sdvo_dtd *dtd)
445{
446 u8 status;
447
448 intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
449 status = intel_sdvo_read_response(intel_output, &dtd->part1,
450 sizeof(dtd->part1));
451 if (status != SDVO_CMD_STATUS_SUCCESS)
452 return false;
453
454 intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
455 status = intel_sdvo_read_response(intel_output, &dtd->part2,
456 sizeof(dtd->part2));
457 if (status != SDVO_CMD_STATUS_SUCCESS)
458 return false;
459
460 return true;
461}
462
463static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
464 struct intel_sdvo_dtd *dtd)
465{
466 return intel_sdvo_get_timing(intel_output,
467 SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
468}
469
470static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
471 struct intel_sdvo_dtd *dtd)
472{
473 return intel_sdvo_get_timing(intel_output,
474 SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
475}
476
477static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
478 struct intel_sdvo_dtd *dtd)
479{
480 u8 status;
481
482 intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
483 status = intel_sdvo_read_response(intel_output, NULL, 0);
484 if (status != SDVO_CMD_STATUS_SUCCESS)
485 return false;
486
487 intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
488 status = intel_sdvo_read_response(intel_output, NULL, 0);
489 if (status != SDVO_CMD_STATUS_SUCCESS)
490 return false;
491
492 return true;
493}
494
495static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
496 struct intel_sdvo_dtd *dtd)
497{
498 return intel_sdvo_set_timing(intel_output,
499 SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
500}
501
502static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
503 struct intel_sdvo_dtd *dtd)
504{
505 return intel_sdvo_set_timing(intel_output,
506 SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
507}
508
509
510static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
511{
512 u8 response, status;
513
514 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
515 status = intel_sdvo_read_response(intel_output, &response, 1);
516
517 if (status != SDVO_CMD_STATUS_SUCCESS) {
518 DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
519 return SDVO_CLOCK_RATE_MULT_1X;
520 } else {
521 DRM_DEBUG("Current clock rate multiplier: %d\n", response);
522 }
523
524 return response;
525}
526
527static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
528{
529 u8 status;
530
531 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
532 status = intel_sdvo_read_response(intel_output, NULL, 0);
533 if (status != SDVO_CMD_STATUS_SUCCESS)
534 return false;
535
536 return true;
537}
538
539static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
540 struct drm_display_mode *mode,
541 struct drm_display_mode *adjusted_mode)
542{
543 /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO
544 * device will be told of the multiplier during mode_set.
545 */
546 adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
547 return true;
548}
549
550static void intel_sdvo_mode_set(struct drm_encoder *encoder,
551 struct drm_display_mode *mode,
552 struct drm_display_mode *adjusted_mode)
553{
554 struct drm_device *dev = encoder->dev;
555 struct drm_i915_private *dev_priv = dev->dev_private;
556 struct drm_crtc *crtc = encoder->crtc;
557 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
558 struct intel_output *intel_output = enc_to_intel_output(encoder);
559 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
560 u16 width, height;
561 u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
562 u16 h_sync_offset, v_sync_offset;
563 u32 sdvox;
564 struct intel_sdvo_dtd output_dtd;
565 int sdvo_pixel_multiply;
566
567 if (!mode)
568 return;
569
570 width = mode->crtc_hdisplay;
571 height = mode->crtc_vdisplay;
572
573 /* do some mode translations */
574 h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
575 h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
576
577 v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
578 v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
579
580 h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
581 v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
582
583 output_dtd.part1.clock = mode->clock / 10;
584 output_dtd.part1.h_active = width & 0xff;
585 output_dtd.part1.h_blank = h_blank_len & 0xff;
586 output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
587 ((h_blank_len >> 8) & 0xf);
588 output_dtd.part1.v_active = height & 0xff;
589 output_dtd.part1.v_blank = v_blank_len & 0xff;
590 output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
591 ((v_blank_len >> 8) & 0xf);
592
593 output_dtd.part2.h_sync_off = h_sync_offset;
594 output_dtd.part2.h_sync_width = h_sync_len & 0xff;
595 output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
596 (v_sync_len & 0xf);
597 output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
598 ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
599 ((v_sync_len & 0x30) >> 4);
600
601 output_dtd.part2.dtd_flags = 0x18;
602 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
603 output_dtd.part2.dtd_flags |= 0x2;
604 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
605 output_dtd.part2.dtd_flags |= 0x4;
606
607 output_dtd.part2.sdvo_flags = 0;
608 output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
609 output_dtd.part2.reserved = 0;
610
611 /* Set the output timing to the screen */
612 intel_sdvo_set_target_output(intel_output, sdvo_priv->active_outputs);
613 intel_sdvo_set_output_timing(intel_output, &output_dtd);
614
615 /* Set the input timing to the screen. Assume always input 0. */
616 intel_sdvo_set_target_input(intel_output, true, false);
617
618 /* We would like to use i830_sdvo_create_preferred_input_timing() to
619 * provide the device with a timing it can support, if it supports that
620 * feature. However, presumably we would need to adjust the CRTC to
621 * output the preferred timing, and we don't support that currently.
622 */
623 intel_sdvo_set_input_timing(intel_output, &output_dtd);
624
625 switch (intel_sdvo_get_pixel_multiplier(mode)) {
626 case 1:
627 intel_sdvo_set_clock_rate_mult(intel_output,
628 SDVO_CLOCK_RATE_MULT_1X);
629 break;
630 case 2:
631 intel_sdvo_set_clock_rate_mult(intel_output,
632 SDVO_CLOCK_RATE_MULT_2X);
633 break;
634 case 4:
635 intel_sdvo_set_clock_rate_mult(intel_output,
636 SDVO_CLOCK_RATE_MULT_4X);
637 break;
638 }
639
640 /* Set the SDVO control regs. */
641 if (0/*IS_I965GM(dev)*/) {
642 sdvox = SDVO_BORDER_ENABLE;
643 } else {
644 sdvox = I915_READ(sdvo_priv->output_device);
645 switch (sdvo_priv->output_device) {
646 case SDVOB:
647 sdvox &= SDVOB_PRESERVE_MASK;
648 break;
649 case SDVOC:
650 sdvox &= SDVOC_PRESERVE_MASK;
651 break;
652 }
653 sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
654 }
655 if (intel_crtc->pipe == 1)
656 sdvox |= SDVO_PIPE_B_SELECT;
657
658 sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
659 if (IS_I965G(dev)) {
660 /* done in crtc_mode_set as the dpll_md reg must be written
661 early */
662 } else if (IS_I945G(dev) || IS_I945GM(dev)) {
663 /* done in crtc_mode_set as it lives inside the
664 dpll register */
665 } else {
666 sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
667 }
668
669 intel_sdvo_write_sdvox(intel_output, sdvox);
670}
671
672static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
673{
674 struct drm_device *dev = encoder->dev;
675 struct drm_i915_private *dev_priv = dev->dev_private;
676 struct intel_output *intel_output = enc_to_intel_output(encoder);
677 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
678 u32 temp;
679
680 if (mode != DRM_MODE_DPMS_ON) {
681 intel_sdvo_set_active_outputs(intel_output, 0);
682 if (0)
683 intel_sdvo_set_encoder_power_state(intel_output, mode);
684
685 if (mode == DRM_MODE_DPMS_OFF) {
686 temp = I915_READ(sdvo_priv->output_device);
687 if ((temp & SDVO_ENABLE) != 0) {
688 intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
689 }
690 }
691 } else {
692 bool input1, input2;
693 int i;
694 u8 status;
695
696 temp = I915_READ(sdvo_priv->output_device);
697 if ((temp & SDVO_ENABLE) == 0)
698 intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
699 for (i = 0; i < 2; i++)
700 intel_wait_for_vblank(dev);
701
702 status = intel_sdvo_get_trained_inputs(intel_output, &input1,
703 &input2);
704
705
706 /* Warn if the device reported failure to sync.
707 * A lot of SDVO devices fail to notify of sync, but it's
708 * a given it the status is a success, we succeeded.
709 */
710 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
711 DRM_DEBUG("First %s output reported failure to sync\n",
712 SDVO_NAME(sdvo_priv));
713 }
714
715 if (0)
716 intel_sdvo_set_encoder_power_state(intel_output, mode);
717 intel_sdvo_set_active_outputs(intel_output, sdvo_priv->active_outputs);
718 }
719 return;
720}
721
722static void intel_sdvo_save(struct drm_connector *connector)
723{
724 struct drm_device *dev = connector->dev;
725 struct drm_i915_private *dev_priv = dev->dev_private;
726 struct intel_output *intel_output = to_intel_output(connector);
727 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
728 int o;
729
730 sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
731 intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
732
733 if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
734 intel_sdvo_set_target_input(intel_output, true, false);
735 intel_sdvo_get_input_timing(intel_output,
736 &sdvo_priv->save_input_dtd_1);
737 }
738
739 if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
740 intel_sdvo_set_target_input(intel_output, false, true);
741 intel_sdvo_get_input_timing(intel_output,
742 &sdvo_priv->save_input_dtd_2);
743 }
744
745 for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
746 {
747 u16 this_output = (1 << o);
748 if (sdvo_priv->caps.output_flags & this_output)
749 {
750 intel_sdvo_set_target_output(intel_output, this_output);
751 intel_sdvo_get_output_timing(intel_output,
752 &sdvo_priv->save_output_dtd[o]);
753 }
754 }
755
756 sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
757}
758
759static void intel_sdvo_restore(struct drm_connector *connector)
760{
761 struct drm_device *dev = connector->dev;
762 struct drm_i915_private *dev_priv = dev->dev_private;
763 struct intel_output *intel_output = to_intel_output(connector);
764 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
765 int o;
766 int i;
767 bool input1, input2;
768 u8 status;
769
770 intel_sdvo_set_active_outputs(intel_output, 0);
771
772 for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
773 {
774 u16 this_output = (1 << o);
775 if (sdvo_priv->caps.output_flags & this_output) {
776 intel_sdvo_set_target_output(intel_output, this_output);
777 intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
778 }
779 }
780
781 if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
782 intel_sdvo_set_target_input(intel_output, true, false);
783 intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
784 }
785
786 if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
787 intel_sdvo_set_target_input(intel_output, false, true);
788 intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
789 }
790
791 intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
792
793 I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
794
795 if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
796 {
797 for (i = 0; i < 2; i++)
798 intel_wait_for_vblank(dev);
799 status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
800 if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
801 DRM_DEBUG("First %s output reported failure to sync\n",
802 SDVO_NAME(sdvo_priv));
803 }
804
805 intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
806}
807
808static int intel_sdvo_mode_valid(struct drm_connector *connector,
809 struct drm_display_mode *mode)
810{
811 struct intel_output *intel_output = to_intel_output(connector);
812 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
813
814 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
815 return MODE_NO_DBLESCAN;
816
817 if (sdvo_priv->pixel_clock_min > mode->clock)
818 return MODE_CLOCK_LOW;
819
820 if (sdvo_priv->pixel_clock_max < mode->clock)
821 return MODE_CLOCK_HIGH;
822
823 return MODE_OK;
824}
825
826static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
827{
828 u8 status;
829
830 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
831 status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
832 if (status != SDVO_CMD_STATUS_SUCCESS)
833 return false;
834
835 return true;
836}
837
838struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
839{
840 struct drm_connector *connector = NULL;
841 struct intel_output *iout = NULL;
842 struct intel_sdvo_priv *sdvo;
843
844 /* find the sdvo connector */
845 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
846 iout = to_intel_output(connector);
847
848 if (iout->type != INTEL_OUTPUT_SDVO)
849 continue;
850
851 sdvo = iout->dev_priv;
852
853 if (sdvo->output_device == SDVOB && sdvoB)
854 return connector;
855
856 if (sdvo->output_device == SDVOC && !sdvoB)
857 return connector;
858
859 }
860
861 return NULL;
862}
863
864int intel_sdvo_supports_hotplug(struct drm_connector *connector)
865{
866 u8 response[2];
867 u8 status;
868 struct intel_output *intel_output;
869 DRM_DEBUG("\n");
870
871 if (!connector)
872 return 0;
873
874 intel_output = to_intel_output(connector);
875
876 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
877 status = intel_sdvo_read_response(intel_output, &response, 2);
878
879 if (response[0] !=0)
880 return 1;
881
882 return 0;
883}
884
885void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
886{
887 u8 response[2];
888 u8 status;
889 struct intel_output *intel_output = to_intel_output(connector);
890
891 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
892 intel_sdvo_read_response(intel_output, &response, 2);
893
894 if (on) {
895 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
896 status = intel_sdvo_read_response(intel_output, &response, 2);
897
898 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
899 } else {
900 response[0] = 0;
901 response[1] = 0;
902 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
903 }
904
905 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
906 intel_sdvo_read_response(intel_output, &response, 2);
907}
908
909static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
910{
911 u8 response[2];
912 u8 status;
913 struct intel_output *intel_output = to_intel_output(connector);
914
915 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
916 status = intel_sdvo_read_response(intel_output, &response, 2);
917
918 DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
919 if ((response[0] != 0) || (response[1] != 0))
920 return connector_status_connected;
921 else
922 return connector_status_disconnected;
923}
924
925static int intel_sdvo_get_modes(struct drm_connector *connector)
926{
927 struct intel_output *intel_output = to_intel_output(connector);
928
929 /* set the bus switch and get the modes */
930 intel_sdvo_set_control_bus_switch(intel_output, SDVO_CONTROL_BUS_DDC2);
931 intel_ddc_get_modes(intel_output);
932
933 if (list_empty(&connector->probed_modes))
934 return 0;
935 return 1;
936}
937
938static void intel_sdvo_destroy(struct drm_connector *connector)
939{
940 struct intel_output *intel_output = to_intel_output(connector);
941
942 if (intel_output->i2c_bus)
943 intel_i2c_destroy(intel_output->i2c_bus);
944 drm_sysfs_connector_remove(connector);
945 drm_connector_cleanup(connector);
946 kfree(intel_output);
947}
948
949static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
950 .dpms = intel_sdvo_dpms,
951 .mode_fixup = intel_sdvo_mode_fixup,
952 .prepare = intel_encoder_prepare,
953 .mode_set = intel_sdvo_mode_set,
954 .commit = intel_encoder_commit,
955};
956
957static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
958 .save = intel_sdvo_save,
959 .restore = intel_sdvo_restore,
960 .detect = intel_sdvo_detect,
961 .fill_modes = drm_helper_probe_single_connector_modes,
962 .destroy = intel_sdvo_destroy,
963};
964
965static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
966 .get_modes = intel_sdvo_get_modes,
967 .mode_valid = intel_sdvo_mode_valid,
968 .best_encoder = intel_best_encoder,
969};
970
971static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
972{
973 drm_encoder_cleanup(encoder);
974}
975
976static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
977 .destroy = intel_sdvo_enc_destroy,
978};
979
980
981void intel_sdvo_init(struct drm_device *dev, int output_device)
982{
983 struct drm_connector *connector;
984 struct intel_output *intel_output;
985 struct intel_sdvo_priv *sdvo_priv;
986 struct intel_i2c_chan *i2cbus = NULL;
987 int connector_type;
988 u8 ch[0x40];
989 int i;
990 int encoder_type, output_id;
991
992 intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
993 if (!intel_output) {
994 return;
995 }
996
997 connector = &intel_output->base;
998
999 drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
1000 DRM_MODE_CONNECTOR_Unknown);
1001 drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
1002 sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
1003 intel_output->type = INTEL_OUTPUT_SDVO;
1004
1005 connector->interlace_allowed = 0;
1006 connector->doublescan_allowed = 0;
1007
1008 /* setup the DDC bus. */
1009 if (output_device == SDVOB)
1010 i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
1011 else
1012 i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
1013
1014 if (!i2cbus)
1015 goto err_connector;
1016
1017 sdvo_priv->i2c_bus = i2cbus;
1018
1019 if (output_device == SDVOB) {
1020 output_id = 1;
1021 sdvo_priv->i2c_bus->slave_addr = 0x38;
1022 } else {
1023 output_id = 2;
1024 sdvo_priv->i2c_bus->slave_addr = 0x39;
1025 }
1026
1027 sdvo_priv->output_device = output_device;
1028 intel_output->i2c_bus = i2cbus;
1029 intel_output->dev_priv = sdvo_priv;
1030
1031
1032 /* Read the regs to test if we can talk to the device */
1033 for (i = 0; i < 0x40; i++) {
1034 if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
1035 DRM_DEBUG("No SDVO device found on SDVO%c\n",
1036 output_device == SDVOB ? 'B' : 'C');
1037 goto err_i2c;
1038 }
1039 }
1040
1041 intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
1042
1043 memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs));
1044
1045 /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
1046 if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
1047 {
1048 sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
1049 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1050 encoder_type = DRM_MODE_ENCODER_DAC;
1051 connector_type = DRM_MODE_CONNECTOR_VGA;
1052 }
1053 else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
1054 {
1055 sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
1056 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1057 encoder_type = DRM_MODE_ENCODER_DAC;
1058 connector_type = DRM_MODE_CONNECTOR_VGA;
1059 }
1060 else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
1061 {
1062 sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
1063 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1064 encoder_type = DRM_MODE_ENCODER_TMDS;
1065 connector_type = DRM_MODE_CONNECTOR_DVID;
1066 }
1067 else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
1068 {
1069 sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
1070 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1071 encoder_type = DRM_MODE_ENCODER_TMDS;
1072 connector_type = DRM_MODE_CONNECTOR_DVID;
1073 }
1074 else
1075 {
1076 unsigned char bytes[2];
1077
1078 memcpy (bytes, &sdvo_priv->caps.output_flags, 2);
1079 DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
1080 SDVO_NAME(sdvo_priv),
1081 bytes[0], bytes[1]);
1082 goto err_i2c;
1083 }
1084
1085 drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type);
1086 drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
1087 connector->connector_type = connector_type;
1088
1089 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
1090 drm_sysfs_connector_add(connector);
1091
1092 /* Set the input timing to the screen. Assume always input 0. */
1093 intel_sdvo_set_target_input(intel_output, true, false);
1094
1095 intel_sdvo_get_input_pixel_clock_range(intel_output,
1096 &sdvo_priv->pixel_clock_min,
1097 &sdvo_priv->pixel_clock_max);
1098
1099
1100 DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, "
1101 "clock range %dMHz - %dMHz, "
1102 "input 1: %c, input 2: %c, "
1103 "output 1: %c, output 2: %c\n",
1104 SDVO_NAME(sdvo_priv),
1105 sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
1106 sdvo_priv->caps.device_rev_id,
1107 sdvo_priv->pixel_clock_min / 1000,
1108 sdvo_priv->pixel_clock_max / 1000,
1109 (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
1110 (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
1111 /* check currently supported outputs */
1112 sdvo_priv->caps.output_flags &
1113 (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
1114 sdvo_priv->caps.output_flags &
1115 (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
1116
1117 intel_output->ddc_bus = i2cbus;
1118
1119 return;
1120
1121err_i2c:
1122 intel_i2c_destroy(intel_output->i2c_bus);
1123err_connector:
1124 drm_connector_cleanup(connector);
1125 kfree(intel_output);
1126
1127 return;
1128}
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..fbb35dc56f5c
--- /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
1615static void 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}