Subversion Repositories Kolibri OS

Rev

Rev 2330 | Rev 2342 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2330 Serge 1
/*
2
 * Copyright 2006 Dave Airlie 
3
 * Copyright © 2006-2007 Intel Corporation
4
 *   Jesse Barnes 
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 
27
 */
28
#include 
29
#include 
30
//#include 
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
#include "intel_sdvo_regs.h"
39
 
40
unsigned int hweight16(unsigned int w)
41
{
42
    unsigned int res = w - ((w >> 1) & 0x5555);
43
    res = (res & 0x3333) + ((res >> 2) & 0x3333);
44
    res = (res + (res >> 4)) & 0x0F0F;
45
    return (res + (res >> 8)) & 0x00FF;
46
}
47
 
48
 
49
#define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)
50
#define SDVO_RGB_MASK  (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)
51
#define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)
52
#define SDVO_TV_MASK   (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0)
53
 
54
#define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\
55
                         SDVO_TV_MASK)
56
 
57
#define IS_TV(c)    (c->output_flag & SDVO_TV_MASK)
58
#define IS_TMDS(c)  (c->output_flag & SDVO_TMDS_MASK)
59
#define IS_LVDS(c)  (c->output_flag & SDVO_LVDS_MASK)
60
#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))
61
 
62
 
63
static const char *tv_format_names[] = {
64
    "NTSC_M"   , "NTSC_J"  , "NTSC_443",
65
    "PAL_B"    , "PAL_D"   , "PAL_G"   ,
66
    "PAL_H"    , "PAL_I"   , "PAL_M"   ,
67
    "PAL_N"    , "PAL_NC"  , "PAL_60"  ,
68
    "SECAM_B"  , "SECAM_D" , "SECAM_G" ,
69
    "SECAM_K"  , "SECAM_K1", "SECAM_L" ,
70
    "SECAM_60"
71
};
72
 
73
#define TV_FORMAT_NUM  (sizeof(tv_format_names) / sizeof(*tv_format_names))
74
 
75
struct intel_sdvo {
76
    struct intel_encoder base;
77
 
78
    struct i2c_adapter *i2c;
79
    u8 slave_addr;
80
 
81
    struct i2c_adapter ddc;
82
 
83
    /* Register for the SDVO device: SDVOB or SDVOC */
84
    int sdvo_reg;
85
 
86
    /* Active outputs controlled by this SDVO output */
87
    uint16_t controlled_output;
88
 
89
    /*
90
     * Capabilities of the SDVO device returned by
91
     * i830_sdvo_get_capabilities()
92
     */
93
    struct intel_sdvo_caps caps;
94
 
95
    /* Pixel clock limitations reported by the SDVO device, in kHz */
96
    int pixel_clock_min, pixel_clock_max;
97
 
98
    /*
99
    * For multiple function SDVO device,
100
    * this is for current attached outputs.
101
    */
102
    uint16_t attached_output;
103
 
104
    /**
105
     * This is used to select the color range of RBG outputs in HDMI mode.
106
     * It is only valid when using TMDS encoding and 8 bit per color mode.
107
     */
108
    uint32_t color_range;
109
 
110
    /**
111
     * This is set if we're going to treat the device as TV-out.
112
     *
113
     * While we have these nice friendly flags for output types that ought
114
     * to decide this for us, the S-Video output on our HDMI+S-Video card
115
     * shows up as RGB1 (VGA).
116
     */
117
    bool is_tv;
118
 
119
    /* This is for current tv format name */
120
    int tv_format_index;
121
 
122
    /**
123
     * This is set if we treat the device as HDMI, instead of DVI.
124
     */
125
    bool is_hdmi;
126
    bool has_hdmi_monitor;
127
    bool has_hdmi_audio;
128
 
129
    /**
130
     * This is set if we detect output of sdvo device as LVDS and
131
     * have a valid fixed mode to use with the panel.
132
     */
133
    bool is_lvds;
134
 
135
    /**
136
     * This is sdvo fixed pannel mode pointer
137
     */
138
    struct drm_display_mode *sdvo_lvds_fixed_mode;
139
 
140
    /* DDC bus used by this SDVO encoder */
141
    uint8_t ddc_bus;
142
 
143
    /* Input timings for adjusted_mode */
144
    struct intel_sdvo_dtd input_dtd;
145
};
146
 
147
struct intel_sdvo_connector {
148
    struct intel_connector base;
149
 
150
    /* Mark the type of connector */
151
    uint16_t output_flag;
152
 
153
    int force_audio;
154
 
155
    /* This contains all current supported TV format */
156
    u8 tv_format_supported[TV_FORMAT_NUM];
157
    int   format_supported_num;
158
    struct drm_property *tv_format;
159
 
160
    /* add the property for the SDVO-TV */
161
    struct drm_property *left;
162
    struct drm_property *right;
163
    struct drm_property *top;
164
    struct drm_property *bottom;
165
    struct drm_property *hpos;
166
    struct drm_property *vpos;
167
    struct drm_property *contrast;
168
    struct drm_property *saturation;
169
    struct drm_property *hue;
170
    struct drm_property *sharpness;
171
    struct drm_property *flicker_filter;
172
    struct drm_property *flicker_filter_adaptive;
173
    struct drm_property *flicker_filter_2d;
174
    struct drm_property *tv_chroma_filter;
175
    struct drm_property *tv_luma_filter;
176
    struct drm_property *dot_crawl;
177
 
178
    /* add the property for the SDVO-TV/LVDS */
179
    struct drm_property *brightness;
180
 
181
    /* Add variable to record current setting for the above property */
182
    u32 left_margin, right_margin, top_margin, bottom_margin;
183
 
184
    /* this is to get the range of margin.*/
185
    u32 max_hscan,  max_vscan;
186
    u32 max_hpos, cur_hpos;
187
    u32 max_vpos, cur_vpos;
188
    u32 cur_brightness, max_brightness;
189
    u32 cur_contrast,   max_contrast;
190
    u32 cur_saturation, max_saturation;
191
    u32 cur_hue,    max_hue;
192
    u32 cur_sharpness,  max_sharpness;
193
    u32 cur_flicker_filter,     max_flicker_filter;
194
    u32 cur_flicker_filter_adaptive,    max_flicker_filter_adaptive;
195
    u32 cur_flicker_filter_2d,      max_flicker_filter_2d;
196
    u32 cur_tv_chroma_filter,   max_tv_chroma_filter;
197
    u32 cur_tv_luma_filter, max_tv_luma_filter;
198
    u32 cur_dot_crawl,  max_dot_crawl;
199
};
200
 
201
static struct intel_sdvo *to_intel_sdvo(struct drm_encoder *encoder)
202
{
203
    return container_of(encoder, struct intel_sdvo, base.base);
204
}
205
 
206
static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector)
207
{
208
	return container_of(intel_attached_encoder(connector),
209
			    struct intel_sdvo, base);
210
}
211
 
212
static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector)
213
{
214
	return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base);
215
}
216
 
217
static bool
218
intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags);
219
static bool
220
intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
221
			      struct intel_sdvo_connector *intel_sdvo_connector,
222
			      int type);
223
static bool
224
intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
225
				   struct intel_sdvo_connector *intel_sdvo_connector);
226
 
227
/**
228
 * Writes the SDVOB or SDVOC with the given value, but always writes both
229
 * SDVOB and SDVOC to work around apparent hardware issues (according to
230
 * comments in the BIOS).
231
 */
232
static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val)
233
{
234
	struct drm_device *dev = intel_sdvo->base.base.dev;
235
	struct drm_i915_private *dev_priv = dev->dev_private;
236
	u32 bval = val, cval = val;
237
	int i;
238
 
239
	if (intel_sdvo->sdvo_reg == PCH_SDVOB) {
240
		I915_WRITE(intel_sdvo->sdvo_reg, val);
241
		I915_READ(intel_sdvo->sdvo_reg);
242
		return;
243
	}
244
 
245
	if (intel_sdvo->sdvo_reg == SDVOB) {
246
		cval = I915_READ(SDVOC);
247
	} else {
248
		bval = I915_READ(SDVOB);
249
	}
250
	/*
251
	 * Write the registers twice for luck. Sometimes,
252
	 * writing them only once doesn't appear to 'stick'.
253
	 * The BIOS does this too. Yay, magic
254
	 */
255
	for (i = 0; i < 2; i++)
256
	{
257
		I915_WRITE(SDVOB, bval);
258
		I915_READ(SDVOB);
259
		I915_WRITE(SDVOC, cval);
260
		I915_READ(SDVOC);
261
	}
262
}
263
 
264
static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch)
265
{
266
	struct i2c_msg msgs[] = {