Subversion Repositories Kolibri OS

Rev

Rev 2330 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2327 Serge 1
/*
2
 * Copyright © 2008 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 DEALINGS
21
 * IN THE SOFTWARE.
22
 *
23
 * Authors:
24
 *    Keith Packard 
25
 *
26
 */
27
 
28
#include 
29
//#include 
30
#include "drmP.h"
31
#include "drm.h"
32
#include "drm_crtc.h"
33
#include "drm_crtc_helper.h"
34
#include "intel_drv.h"
35
//#include "i915_drm.h"
36
#include "i915_drv.h"
37
#include "drm_dp_helper.h"
38
 
39
 
40
#define DP_LINK_STATUS_SIZE 6
41
#define DP_LINK_CHECK_TIMEOUT   (10 * 1000)
42
 
43
#define DP_LINK_CONFIGURATION_SIZE  9
44
 
45
struct intel_dp {
46
    struct intel_encoder base;
47
    uint32_t output_reg;
48
    uint32_t DP;
49
    uint8_t  link_configuration[DP_LINK_CONFIGURATION_SIZE];
50
    bool has_audio;
51
    int force_audio;
52
    uint32_t color_range;
53
    int dpms_mode;
54
    uint8_t link_bw;
55
    uint8_t lane_count;
56
    uint8_t dpcd[8];
57
    struct i2c_adapter adapter;
58
    struct i2c_algo_dp_aux_data algo;
59
    bool is_pch_edp;
60
    uint8_t train_set[4];
61
    uint8_t link_status[DP_LINK_STATUS_SIZE];
62
};
63
 
64
/**
65
 * is_edp - is the given port attached to an eDP panel (either CPU or PCH)
66
 * @intel_dp: DP struct
67
 *
68
 * If a CPU or PCH DP output is attached to an eDP panel, this function
69
 * will return true, and false otherwise.
70
 */
71
static bool is_edp(struct intel_dp *intel_dp)
72
{
73
	return intel_dp->base.type == INTEL_OUTPUT_EDP;
74
}
75
 
76
/**
77
 * is_pch_edp - is the port on the PCH and attached to an eDP panel?
78
 * @intel_dp: DP struct
79
 *
80
 * Returns true if the given DP struct corresponds to a PCH DP port attached
81
 * to an eDP panel, false otherwise.  Helpful for determining whether we
82
 * may need FDI resources for a given DP output or not.
83
 */
84
static bool is_pch_edp(struct intel_dp *intel_dp)
85
{
86
	return intel_dp->is_pch_edp;
87
}
88
 
89
static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
90
{
91
	return container_of(encoder, struct intel_dp, base.base);
92
}
93
 
94
 
95
 
96
 
97
 
98
/**
99
 * intel_encoder_is_pch_edp - is the given encoder a PCH attached eDP?
100
 * @encoder: DRM encoder
101
 *
102
 * Return true if @encoder corresponds to a PCH attached eDP panel.  Needed
103
 * by intel_display.c.
104
 */
105
bool intel_encoder_is_pch_edp(struct drm_encoder *encoder)
106
{
107
    struct intel_dp *intel_dp;
108
 
109
    if (!encoder)
110
        return false;
111
 
112
    intel_dp = enc_to_intel_dp(encoder);
113
 
114
    return is_pch_edp(intel_dp);
115
}
116
 
117
void
118
intel_edp_link_config (struct intel_encoder *intel_encoder,
119
		       int *lane_num, int *link_bw)
120
{
121
	struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base);
122
 
123
	*lane_num = intel_dp->lane_count;
124
	if (intel_dp->link_bw == DP_LINK_BW_1_62)
125
		*link_bw = 162000;
126
	else if (intel_dp->link_bw == DP_LINK_BW_2_7)
127
		*link_bw = 270000;
128
}
129
 
130
 
131
 
132
 
133
 
134
 
135
 
136
 
137
 
138
 
139
 
140
 
141
 
142
 
143
struct intel_dp_m_n {
144
	uint32_t	tu;
145
	uint32_t	gmch_m;
146
	uint32_t	gmch_n;
147
	uint32_t	link_m;
148
	uint32_t	link_n;
149
};
150
 
151
static void
152
intel_reduce_ratio(uint32_t *num, uint32_t *den)
153
{
154
	while (*num > 0xffffff || *den > 0xffffff) {
155
		*num >>= 1;
156
		*den >>= 1;
157
	}
158
}
159
 
160
static void
161
intel_dp_compute_m_n(int bpp,
162
		     int nlanes,
163
		     int pixel_clock,
164
		     int link_clock,
165
		     struct intel_dp_m_n *m_n)
166
{
167
	m_n->tu = 64;
168
	m_n->gmch_m = (pixel_clock * bpp) >> 3;
169
	m_n->gmch_n = link_clock * nlanes;
170
	intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
171
	m_n->link_m = pixel_clock;
172
	m_n->link_n = link_clock;
173
	intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
174
}
175
 
176
void
177
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
178
         struct drm_display_mode *adjusted_mode)
179
{
180
    struct drm_device *dev = crtc->dev;
181
    struct drm_mode_config *mode_config = &dev->mode_config;
182
    struct drm_encoder *encoder;
183
    struct drm_i915_private *dev_priv = dev->dev_private;
184
    struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
185
    int lane_count = 4;
186
    struct intel_dp_m_n m_n;
187
    int pipe = intel_crtc->pipe;
188
 
189
    /*
190
     * Find the lane count in the intel_encoder private
191
     */
192
    list_for_each_entry(encoder, &mode_config->encoder_list, head) {
193
        struct intel_dp *intel_dp;
194
 
195
        if (encoder->crtc != crtc)
196
            continue;
197
 
198
        intel_dp = enc_to_intel_dp(encoder);
199
        if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) {
200
            lane_count = intel_dp->lane_count;
201
            break;
202
        } else if (is_edp(intel_dp)) {
203
            lane_count = dev_priv->edp.lanes;
204
            break;
205
        }
206
    }
207
 
208
    /*
209
     * Compute the GMCH and Link ratios. The '3' here is
210
     * the number of bytes_per_pixel post-LUT, which we always
211
     * set up for 8-bits of R/G/B, or 3 bytes total.
212
     */
213
    intel_dp_compute_m_n(intel_crtc->bpp, lane_count,
214
                 mode->clock, adjusted_mode->clock, &m_n);
215
 
216
    if (HAS_PCH_SPLIT(dev)) {
217
        I915_WRITE(TRANSDATA_M1(pipe),
218
               ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
219
               m_n.gmch_m);
220
        I915_WRITE(TRANSDATA_N1(pipe), m_n.gmch_n);
221
        I915_WRITE(TRANSDPLINK_M1(pipe), m_n.link_m);
222
        I915_WRITE(TRANSDPLINK_N1(pipe), m_n.link_n);
223
    } else {
224
        I915_WRITE(PIPE_GMCH_DATA_M(pipe),
225
               ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) |
226
               m_n.gmch_m);
227
        I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n.gmch_n);
228
        I915_WRITE(PIPE_DP_LINK_M(pipe), m_n.link_m);
229
        I915_WRITE(PIPE_DP_LINK_N(pipe), m_n.link_n);
230
    }
231
}
232
 
233
 
234
 
235
 
236
 
237
 
238
 
239
 
240
 
241
 
242
 
243
 
244
 
245
 
246
 
247
 
248
 
249
 
250
 
251
 
252
 
253
 
254
 
255
 
256
 
257
 
258
 
259
 
260
 
261
 
262
 
263
 
264
 
265
 
266
 
267
 
268
 
269
 
270
 
271
 
272
 
273
 
274
 
275
 
276
 
277
 
278
 
279
 
280
/* Return which DP Port should be selected for Transcoder DP control */
281
int
282
intel_trans_dp_port_sel (struct drm_crtc *crtc)
283
{
284
	struct drm_device *dev = crtc->dev;
285
	struct drm_mode_config *mode_config = &dev->mode_config;
286
	struct drm_encoder *encoder;
287
 
288
	list_for_each_entry(encoder, &mode_config->encoder_list, head) {
289
		struct intel_dp *intel_dp;
290
 
291
		if (encoder->crtc != crtc)
292
			continue;
293
 
294
		intel_dp = enc_to_intel_dp(encoder);
295
		if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT)
296
			return intel_dp->output_reg;
297
	}
298
 
299
	return -1;
300
}