aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/gma500
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2012-08-08 09:55:55 -0400
committerDave Airlie <airlied@redhat.com>2012-08-23 19:29:25 -0400
commitd112a8163f83752361dd639a9a579ae5cc05c6cf (patch)
tree53a97ff373718223d0b46cb6d74dc81906058439 /drivers/gpu/drm/gma500
parent35659715c42b5cd148935e8ebd4e5e8e4e256b96 (diff)
gma500/cdv: Add eDP support
Introduce the eDP support into the driver. This has been reworked a bit because kernel driver proper uses encoder/connectors while the legacy Intel driver uses the old output stuff. It also diverges on the backlight handling. The legacy Intel driver adds a panel abstraction based upon the i915 one. It's only really used for backlight bits and we have a perfectly good backlight abstraction which can extend instead. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> [ported to upstream driver, redid backlight abstraction] Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/gma500')
-rw-r--r--drivers/gpu/drm/gma500/backlight.c45
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c1
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_display.c42
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_dp.c468
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_lvds.c12
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c3
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.c101
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.h46
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_output.c13
-rw-r--r--drivers/gpu/drm/gma500/mid_bios.c8
-rw-r--r--drivers/gpu/drm/gma500/opregion.c3
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h19
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_lvds.c13
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_reg.h38
14 files changed, 751 insertions, 61 deletions
diff --git a/drivers/gpu/drm/gma500/backlight.c b/drivers/gpu/drm/gma500/backlight.c
index 20793951fcac..143eba3309c5 100644
--- a/drivers/gpu/drm/gma500/backlight.c
+++ b/drivers/gpu/drm/gma500/backlight.c
@@ -26,10 +26,55 @@
26#include "intel_bios.h" 26#include "intel_bios.h"
27#include "power.h" 27#include "power.h"
28 28
29static void do_gma_backlight_set(struct drm_device *dev)
30{
31#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
32 struct drm_psb_private *dev_priv = dev->dev_private;
33 backlight_update_status(dev_priv->backlight_device);
34#endif
35}
36
37void gma_backlight_enable(struct drm_device *dev)
38{
39#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
40 struct drm_psb_private *dev_priv = dev->dev_private;
41 dev_priv->backlight_enabled = true;
42 if (dev_priv->backlight_device) {
43 dev_priv->backlight_device->props.brightness = dev_priv->backlight_level;
44 do_gma_backlight_set(dev);
45 }
46#endif
47}
48
49void gma_backlight_disable(struct drm_device *dev)
50{
51#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
52 struct drm_psb_private *dev_priv = dev->dev_private;
53 dev_priv->backlight_enabled = false;
54 if (dev_priv->backlight_device) {
55 dev_priv->backlight_device->props.brightness = 0;
56 do_gma_backlight_set(dev);
57 }
58#endif
59}
60
61void gma_backlight_set(struct drm_device *dev, int v)
62{
63#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
64 struct drm_psb_private *dev_priv = dev->dev_private;
65 dev_priv->backlight_level = v;
66 if (dev_priv->backlight_device && dev_priv->backlight_enabled) {
67 dev_priv->backlight_device->props.brightness = v;
68 do_gma_backlight_set(dev);
69 }
70#endif
71}
72
29int gma_backlight_init(struct drm_device *dev) 73int gma_backlight_init(struct drm_device *dev)
30{ 74{
31#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 75#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
32 struct drm_psb_private *dev_priv = dev->dev_private; 76 struct drm_psb_private *dev_priv = dev->dev_private;
77 dev_priv->backlight_enabled = true;
33 return dev_priv->ops->backlight_init(dev); 78 return dev_priv->ops->backlight_init(dev);
34#else 79#else
35 return 0; 80 return 0;
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index 68f100e67135..4882e642eec3 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -170,6 +170,7 @@ static int cdv_backlight_init(struct drm_device *dev)
170 cdv_get_brightness(cdv_backlight_device); 170 cdv_get_brightness(cdv_backlight_device);
171 backlight_update_status(cdv_backlight_device); 171 backlight_update_status(cdv_backlight_device);
172 dev_priv->backlight_device = cdv_backlight_device; 172 dev_priv->backlight_device = cdv_backlight_device;
173 dev_priv->backlight_enabled = true;
173 return 0; 174 return 0;
174} 175}
175 176
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c
index 3f1106096ad3..bfb056561777 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_display.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -438,7 +438,8 @@ static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
438 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96]; 438 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
439 else 439 else
440 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100]; 440 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
441 } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { 441 } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
442 psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
442 if (refclk == 27000) 443 if (refclk == 27000)
443 limit = &cdv_intel_limits[CDV_LIMIT_DP_27]; 444 limit = &cdv_intel_limits[CDV_LIMIT_DP_27];
444 else 445 else
@@ -1045,6 +1046,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1045 struct drm_connector *connector; 1046 struct drm_connector *connector;
1046 const struct cdv_intel_limit_t *limit; 1047 const struct cdv_intel_limit_t *limit;
1047 u32 ddi_select = 0; 1048 u32 ddi_select = 0;
1049 bool is_edp = false;
1048 1050
1049 list_for_each_entry(connector, &mode_config->connector_list, head) { 1051 list_for_each_entry(connector, &mode_config->connector_list, head) {
1050 struct psb_intel_encoder *psb_intel_encoder = 1052 struct psb_intel_encoder *psb_intel_encoder =
@@ -1071,6 +1073,9 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1071 case INTEL_OUTPUT_DISPLAYPORT: 1073 case INTEL_OUTPUT_DISPLAYPORT:
1072 is_dp = true; 1074 is_dp = true;
1073 break; 1075 break;
1076 case INTEL_OUTPUT_EDP:
1077 is_edp = true;
1078 break;
1074 default: 1079 default:
1075 DRM_ERROR("invalid output type.\n"); 1080 DRM_ERROR("invalid output type.\n");
1076 return 0; 1081 return 0;
@@ -1083,7 +1088,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1083 else 1088 else
1084 /* high-end sku, 27/100 mhz */ 1089 /* high-end sku, 27/100 mhz */
1085 refclk = 27000; 1090 refclk = 27000;
1086 if (is_dp) { 1091 if (is_dp || is_edp) {
1092 /*
1093 * Based on the spec the low-end SKU has only CRT/LVDS. So it is
1094 * unnecessary to consider it for DP/eDP.
1095 * On the high-end SKU, it will use the 27/100M reference clk
1096 * for DP/eDP. When using SSC clock, the ref clk is 100MHz.Otherwise
1097 * it will be 27MHz. From the VBIOS code it seems that the pipe A choose
1098 * 27MHz for DP/eDP while the Pipe B chooses the 100MHz.
1099 */
1087 if (pipe == 0) 1100 if (pipe == 0)
1088 refclk = 27000; 1101 refclk = 27000;
1089 else 1102 else
@@ -1133,6 +1146,31 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1133 /* setup pipeconf */ 1146 /* setup pipeconf */
1134 pipeconf = REG_READ(map->conf); 1147 pipeconf = REG_READ(map->conf);
1135 1148
1149 pipeconf &= ~(PIPE_BPC_MASK);
1150 if (is_edp) {
1151 switch (dev_priv->edp.bpp) {
1152 case 24:
1153 pipeconf |= PIPE_8BPC;
1154 break;
1155 case 18:
1156 pipeconf |= PIPE_6BPC;
1157 break;
1158 case 30:
1159 pipeconf |= PIPE_10BPC;
1160 break;
1161 default:
1162 pipeconf |= PIPE_8BPC;
1163 break;
1164 }
1165 } else if (is_lvds) {
1166 /* the BPC will be 6 if it is 18-bit LVDS panel */
1167 if ((REG_READ(LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
1168 pipeconf |= PIPE_8BPC;
1169 else
1170 pipeconf |= PIPE_6BPC;
1171 } else
1172 pipeconf |= PIPE_8BPC;
1173
1136 /* Set up the display plane register */ 1174 /* Set up the display plane register */
1137 dspcntr = DISPPLANE_GAMMA_ENABLE; 1175 dspcntr = DISPPLANE_GAMMA_ENABLE;
1138 1176
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c
index b29b6026b6ef..0571ef9b889b 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_dp.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c
@@ -36,6 +36,20 @@
36#include "psb_intel_reg.h" 36#include "psb_intel_reg.h"
37#include "drm_dp_helper.h" 37#include "drm_dp_helper.h"
38 38
39#define _wait_for(COND, MS, W) ({ \
40 unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
41 int ret__ = 0; \
42 while (! (COND)) { \
43 if (time_after(jiffies, timeout__)) { \
44 ret__ = -ETIMEDOUT; \
45 break; \
46 } \
47 if (W && !in_dbg_master()) msleep(W); \
48 } \
49 ret__; \
50})
51
52#define wait_for(COND, MS) _wait_for(COND, MS, 1)
39 53
40#define DP_LINK_STATUS_SIZE 6 54#define DP_LINK_STATUS_SIZE 6
41#define DP_LINK_CHECK_TIMEOUT (10 * 1000) 55#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
@@ -59,6 +73,13 @@ struct cdv_intel_dp {
59 struct i2c_algo_dp_aux_data algo; 73 struct i2c_algo_dp_aux_data algo;
60 uint8_t train_set[4]; 74 uint8_t train_set[4];
61 uint8_t link_status[DP_LINK_STATUS_SIZE]; 75 uint8_t link_status[DP_LINK_STATUS_SIZE];
76 int panel_power_up_delay;
77 int panel_power_down_delay;
78 int panel_power_cycle_delay;
79 int backlight_on_delay;
80 int backlight_off_delay;
81 struct drm_display_mode *panel_fixed_mode; /* for eDP */
82 bool panel_on;
62}; 83};
63 84
64struct ddi_regoff { 85struct ddi_regoff {
@@ -159,31 +180,166 @@ cdv_intel_dp_max_data_rate(int max_link_clock, int max_lanes)
159 return (max_link_clock * max_lanes * 19) / 20; 180 return (max_link_clock * max_lanes * 19) / 20;
160} 181}
161 182
183static void cdv_intel_edp_panel_vdd_on(struct psb_intel_encoder *intel_encoder)
184{
185 struct drm_device *dev = intel_encoder->base.dev;
186 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
187 u32 pp;
188
189 if (intel_dp->panel_on) {
190 DRM_DEBUG_KMS("Skip VDD on because of panel on\n");
191 return;
192 }
193 DRM_DEBUG_KMS("\n");
194
195 pp = REG_READ(PP_CONTROL);
196
197 pp |= EDP_FORCE_VDD;
198 REG_WRITE(PP_CONTROL, pp);
199 REG_READ(PP_CONTROL);
200 msleep(intel_dp->panel_power_up_delay);
201}
202
203static void cdv_intel_edp_panel_vdd_off(struct psb_intel_encoder *intel_encoder)
204{
205 struct drm_device *dev = intel_encoder->base.dev;
206 u32 pp;
207
208 DRM_DEBUG_KMS("\n");
209 pp = REG_READ(PP_CONTROL);
210
211 pp &= ~EDP_FORCE_VDD;
212 REG_WRITE(PP_CONTROL, pp);
213 REG_READ(PP_CONTROL);
214
215}
216
217/* Returns true if the panel was already on when called */
218static bool cdv_intel_edp_panel_on(struct psb_intel_encoder *intel_encoder)
219{
220 struct drm_device *dev = intel_encoder->base.dev;
221 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
222 u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_NONE;
223
224 if (intel_dp->panel_on)
225 return true;
226
227 DRM_DEBUG_KMS("\n");
228 pp = REG_READ(PP_CONTROL);
229 pp &= ~PANEL_UNLOCK_MASK;
230
231 pp |= (PANEL_UNLOCK_REGS | POWER_TARGET_ON);
232 REG_WRITE(PP_CONTROL, pp);
233 REG_READ(PP_CONTROL);
234
235 if (wait_for(((REG_READ(PP_STATUS) & idle_on_mask) == idle_on_mask), 1000)) {
236 DRM_DEBUG_KMS("Error in Powering up eDP panel, status %x\n", REG_READ(PP_STATUS));
237 intel_dp->panel_on = false;
238 } else
239 intel_dp->panel_on = true;
240 msleep(intel_dp->panel_power_up_delay);
241
242 return false;
243}
244
245static void cdv_intel_edp_panel_off (struct psb_intel_encoder *intel_encoder)
246{
247 struct drm_device *dev = intel_encoder->base.dev;
248 u32 pp, idle_off_mask = PP_ON ;
249 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
250
251 DRM_DEBUG_KMS("\n");
252
253 pp = REG_READ(PP_CONTROL);
254
255 if ((pp & POWER_TARGET_ON) == 0)
256 return;
257
258 intel_dp->panel_on = false;
259 pp &= ~PANEL_UNLOCK_MASK;
260 /* ILK workaround: disable reset around power sequence */
261
262 pp &= ~POWER_TARGET_ON;
263 pp &= ~EDP_FORCE_VDD;
264 pp &= ~EDP_BLC_ENABLE;
265 REG_WRITE(PP_CONTROL, pp);
266 REG_READ(PP_CONTROL);
267 DRM_DEBUG_KMS("PP_STATUS %x\n", REG_READ(PP_STATUS));
268
269 if (wait_for((REG_READ(PP_STATUS) & idle_off_mask) == 0, 1000)) {
270 DRM_DEBUG_KMS("Error in turning off Panel\n");
271 }
272
273 msleep(intel_dp->panel_power_cycle_delay);
274 DRM_DEBUG_KMS("Over\n");
275}
276
277static void cdv_intel_edp_backlight_on (struct psb_intel_encoder *intel_encoder)
278{
279 struct drm_device *dev = intel_encoder->base.dev;
280 u32 pp;
281
282 DRM_DEBUG_KMS("\n");
283 /*
284 * If we enable the backlight right away following a panel power
285 * on, we may see slight flicker as the panel syncs with the eDP
286 * link. So delay a bit to make sure the image is solid before
287 * allowing it to appear.
288 */
289 msleep(300);
290 pp = REG_READ(PP_CONTROL);
291
292 pp |= EDP_BLC_ENABLE;
293 REG_WRITE(PP_CONTROL, pp);
294 gma_backlight_enable(dev);
295}
296
297static void cdv_intel_edp_backlight_off (struct psb_intel_encoder *intel_encoder)
298{
299 struct drm_device *dev = intel_encoder->base.dev;
300 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
301 u32 pp;
302
303 DRM_DEBUG_KMS("\n");
304 gma_backlight_disable(dev);
305 msleep(10);
306 pp = REG_READ(PP_CONTROL);
307
308 pp &= ~EDP_BLC_ENABLE;
309 REG_WRITE(PP_CONTROL, pp);
310 msleep(intel_dp->backlight_off_delay);
311}
312
162static int 313static int
163cdv_intel_dp_mode_valid(struct drm_connector *connector, 314cdv_intel_dp_mode_valid(struct drm_connector *connector,
164 struct drm_display_mode *mode) 315 struct drm_display_mode *mode)
165{ 316{
166 struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector); 317 struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector);
167 struct drm_device *dev = connector->dev; 318 struct cdv_intel_dp *intel_dp = encoder->dev_priv;
168 struct drm_psb_private *dev_priv = dev->dev_private;
169 int max_link_clock = cdv_intel_dp_link_clock(cdv_intel_dp_max_link_bw(encoder)); 319 int max_link_clock = cdv_intel_dp_link_clock(cdv_intel_dp_max_link_bw(encoder));
170 int max_lanes = cdv_intel_dp_max_lane_count(encoder); 320 int max_lanes = cdv_intel_dp_max_lane_count(encoder);
321 struct drm_psb_private *dev_priv = connector->dev->dev_private;
171 322
172 if (is_edp(encoder) && dev_priv->panel_fixed_mode) { 323 if (is_edp(encoder) && intel_dp->panel_fixed_mode) {
173 if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) 324 if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
174 return MODE_PANEL; 325 return MODE_PANEL;
175 326 if (mode->vdisplay > intel_dp->panel_fixed_mode->vdisplay)
176 if (mode->vdisplay > dev_priv->panel_fixed_mode->vdisplay)
177 return MODE_PANEL; 327 return MODE_PANEL;
178 } 328 }
179 329
180 /* only refuse the mode on non eDP since we have seen some weird eDP panels 330 /* only refuse the mode on non eDP since we have seen some weird eDP panels
181 which are outside spec tolerances but somehow work by magic */ 331 which are outside spec tolerances but somehow work by magic */
182 if (!is_edp(encoder) && 332 if (!is_edp(encoder) &&
183 (cdv_intel_dp_link_required(mode->clock, 24) 333 (cdv_intel_dp_link_required(mode->clock, dev_priv->edp.bpp)
184 > cdv_intel_dp_max_data_rate(max_link_clock, max_lanes))) 334 > cdv_intel_dp_max_data_rate(max_link_clock, max_lanes)))
185 return MODE_CLOCK_HIGH; 335 return MODE_CLOCK_HIGH;
186 336
337 if (is_edp(encoder)) {
338 if (cdv_intel_dp_link_required(mode->clock, 24)
339 > cdv_intel_dp_max_data_rate(max_link_clock, max_lanes))
340 return MODE_CLOCK_HIGH;
341
342 }
187 if (mode->clock < 10000) 343 if (mode->clock < 10000)
188 return MODE_CLOCK_LOW; 344 return MODE_CLOCK_LOW;
189 345
@@ -238,6 +394,8 @@ cdv_intel_dp_aux_ch(struct psb_intel_encoder *encoder,
238 aux_clock_divider = 200 / 2; 394 aux_clock_divider = 200 / 2;
239 395
240 precharge = 4; 396 precharge = 4;
397 if (is_edp(encoder))
398 precharge = 10;
241 399
242 if (REG_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) { 400 if (REG_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) {
243 DRM_ERROR("dp_aux_ch not started status 0x%08x\n", 401 DRM_ERROR("dp_aux_ch not started status 0x%08x\n",
@@ -492,7 +650,10 @@ static int
492cdv_intel_dp_i2c_init(struct psb_intel_connector *connector, struct psb_intel_encoder *encoder, const char *name) 650cdv_intel_dp_i2c_init(struct psb_intel_connector *connector, struct psb_intel_encoder *encoder, const char *name)
493{ 651{
494 struct cdv_intel_dp *intel_dp = encoder->dev_priv; 652 struct cdv_intel_dp *intel_dp = encoder->dev_priv;
653 int ret;
654
495 DRM_DEBUG_KMS("i2c_init %s\n", name); 655 DRM_DEBUG_KMS("i2c_init %s\n", name);
656
496 intel_dp->algo.running = false; 657 intel_dp->algo.running = false;
497 intel_dp->algo.address = 0; 658 intel_dp->algo.address = 0;
498 intel_dp->algo.aux_ch = cdv_intel_dp_i2c_aux_ch; 659 intel_dp->algo.aux_ch = cdv_intel_dp_i2c_aux_ch;
@@ -505,27 +666,58 @@ cdv_intel_dp_i2c_init(struct psb_intel_connector *connector, struct psb_intel_en
505 intel_dp->adapter.algo_data = &intel_dp->algo; 666 intel_dp->adapter.algo_data = &intel_dp->algo;
506 intel_dp->adapter.dev.parent = &connector->base.kdev; 667 intel_dp->adapter.dev.parent = &connector->base.kdev;
507 668
508 return i2c_dp_aux_add_bus(&intel_dp->adapter); 669 if (is_edp(encoder))
670 cdv_intel_edp_panel_vdd_on(encoder);
671 ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
672 if (is_edp(encoder))
673 cdv_intel_edp_panel_vdd_off(encoder);
674
675 return ret;
676}
677
678void cdv_intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
679 struct drm_display_mode *adjusted_mode)
680{
681 adjusted_mode->hdisplay = fixed_mode->hdisplay;
682 adjusted_mode->hsync_start = fixed_mode->hsync_start;
683 adjusted_mode->hsync_end = fixed_mode->hsync_end;
684 adjusted_mode->htotal = fixed_mode->htotal;
685
686 adjusted_mode->vdisplay = fixed_mode->vdisplay;
687 adjusted_mode->vsync_start = fixed_mode->vsync_start;
688 adjusted_mode->vsync_end = fixed_mode->vsync_end;
689 adjusted_mode->vtotal = fixed_mode->vtotal;
690
691 adjusted_mode->clock = fixed_mode->clock;
692
693 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
509} 694}
510 695
511static bool 696static bool
512cdv_intel_dp_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, 697cdv_intel_dp_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode,
513 struct drm_display_mode *adjusted_mode) 698 struct drm_display_mode *adjusted_mode)
514{ 699{
700 struct drm_psb_private *dev_priv = encoder->dev->dev_private;
515 struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); 701 struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder);
516 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; 702 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
517 int lane_count, clock; 703 int lane_count, clock;
518 int max_lane_count = cdv_intel_dp_max_lane_count(intel_encoder); 704 int max_lane_count = cdv_intel_dp_max_lane_count(intel_encoder);
519 int max_clock = cdv_intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; 705 int max_clock = cdv_intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
520 static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; 706 static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
707 int refclock = mode->clock;
708 int bpp = 24;
521 709
710 if (is_edp(intel_encoder) && intel_dp->panel_fixed_mode) {
711 cdv_intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode);
712 refclock = intel_dp->panel_fixed_mode->clock;
713 bpp = dev_priv->edp.bpp;
714 }
522 715
523 for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { 716 for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
524 for (clock = max_clock; clock >= 0; clock--) { 717 for (clock = max_clock; clock >= 0; clock--) {
525 int link_avail = cdv_intel_dp_max_data_rate(cdv_intel_dp_link_clock(bws[clock]), lane_count); 718 int link_avail = cdv_intel_dp_max_data_rate(cdv_intel_dp_link_clock(bws[clock]), lane_count);
526 719
527 if (cdv_intel_dp_link_required(mode->clock, 24) 720 if (cdv_intel_dp_link_required(refclock, bpp) <= link_avail) {
528 <= link_avail) {
529 intel_dp->link_bw = bws[clock]; 721 intel_dp->link_bw = bws[clock];
530 intel_dp->lane_count = lane_count; 722 intel_dp->lane_count = lane_count;
531 adjusted_mode->clock = cdv_intel_dp_link_clock(intel_dp->link_bw); 723 adjusted_mode->clock = cdv_intel_dp_link_clock(intel_dp->link_bw);
@@ -537,7 +729,18 @@ cdv_intel_dp_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mo
537 } 729 }
538 } 730 }
539 } 731 }
540 732 if (is_edp(intel_encoder)) {
733 /* okay we failed just pick the highest */
734 intel_dp->lane_count = max_lane_count;
735 intel_dp->link_bw = bws[max_clock];
736 adjusted_mode->clock = cdv_intel_dp_link_clock(intel_dp->link_bw);
737 DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
738 "count %d clock %d\n",
739 intel_dp->link_bw, intel_dp->lane_count,
740 adjusted_mode->clock);
741
742 return true;
743 }
541 return false; 744 return false;
542} 745}
543 746
@@ -550,7 +753,7 @@ struct cdv_intel_dp_m_n {
550}; 753};
551 754
552static void 755static void
553psb_intel_reduce_ratio(uint32_t *num, uint32_t *den) 756cdv_intel_reduce_ratio(uint32_t *num, uint32_t *den)
554{ 757{
555 /* 758 /*
556 while (*num > 0xffffff || *den > 0xffffff) { 759 while (*num > 0xffffff || *den > 0xffffff) {
@@ -575,10 +778,10 @@ cdv_intel_dp_compute_m_n(int bpp,
575 m_n->tu = 64; 778 m_n->tu = 64;
576 m_n->gmch_m = (pixel_clock * bpp + 7) >> 3; 779 m_n->gmch_m = (pixel_clock * bpp + 7) >> 3;
577 m_n->gmch_n = link_clock * nlanes; 780 m_n->gmch_n = link_clock * nlanes;
578 psb_intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); 781 cdv_intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
579 m_n->link_m = pixel_clock; 782 m_n->link_m = pixel_clock;
580 m_n->link_n = link_clock; 783 m_n->link_n = link_clock;
581 psb_intel_reduce_ratio(&m_n->link_m, &m_n->link_n); 784 cdv_intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
582} 785}
583 786
584void 787void
@@ -586,6 +789,7 @@ cdv_intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
586 struct drm_display_mode *adjusted_mode) 789 struct drm_display_mode *adjusted_mode)
587{ 790{
588 struct drm_device *dev = crtc->dev; 791 struct drm_device *dev = crtc->dev;
792 struct drm_psb_private *dev_priv = dev->dev_private;
589 struct drm_mode_config *mode_config = &dev->mode_config; 793 struct drm_mode_config *mode_config = &dev->mode_config;
590 struct drm_encoder *encoder; 794 struct drm_encoder *encoder;
591 struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); 795 struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
@@ -610,6 +814,7 @@ cdv_intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
610 break; 814 break;
611 } else if (is_edp(intel_encoder)) { 815 } else if (is_edp(intel_encoder)) {
612 lane_count = intel_dp->lane_count; 816 lane_count = intel_dp->lane_count;
817 bpp = dev_priv->edp.bpp;
613 break; 818 break;
614 } 819 }
615 } 820 }
@@ -640,7 +845,7 @@ cdv_intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode
640 struct drm_crtc *crtc = encoder->crtc; 845 struct drm_crtc *crtc = encoder->crtc;
641 struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); 846 struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
642 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; 847 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
643 848 struct drm_device *dev = encoder->dev;
644 849
645 intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; 850 intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
646 intel_dp->DP |= intel_dp->color_range; 851 intel_dp->DP |= intel_dp->color_range;
@@ -683,7 +888,22 @@ cdv_intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode
683 if (intel_crtc->pipe == 1) 888 if (intel_crtc->pipe == 1)
684 intel_dp->DP |= DP_PIPEB_SELECT; 889 intel_dp->DP |= DP_PIPEB_SELECT;
685 890
891 REG_WRITE(intel_dp->output_reg, (intel_dp->DP | DP_PORT_EN));
686 DRM_DEBUG_KMS("DP expected reg is %x\n", intel_dp->DP); 892 DRM_DEBUG_KMS("DP expected reg is %x\n", intel_dp->DP);
893 if (is_edp(intel_encoder)) {
894 uint32_t pfit_control;
895 cdv_intel_edp_panel_on(intel_encoder);
896
897 if (mode->hdisplay != adjusted_mode->hdisplay ||
898 mode->vdisplay != adjusted_mode->vdisplay)
899 pfit_control = PFIT_ENABLE;
900 else
901 pfit_control = 0;
902
903 pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
904
905 REG_WRITE(PFIT_CONTROL, pfit_control);
906 }
687} 907}
688 908
689 909
@@ -721,18 +941,31 @@ static void cdv_intel_dp_sink_dpms(struct psb_intel_encoder *encoder, int mode)
721static void cdv_intel_dp_prepare(struct drm_encoder *encoder) 941static void cdv_intel_dp_prepare(struct drm_encoder *encoder)
722{ 942{
723 struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); 943 struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder);
944 int edp = is_edp(intel_encoder);
724 945
946 if (edp) {
947 cdv_intel_edp_backlight_off(intel_encoder);
948 cdv_intel_edp_panel_off(intel_encoder);
949 cdv_intel_edp_panel_vdd_on(intel_encoder);
950 }
725 /* Wake up the sink first */ 951 /* Wake up the sink first */
726 cdv_intel_dp_sink_dpms(intel_encoder, DRM_MODE_DPMS_ON); 952 cdv_intel_dp_sink_dpms(intel_encoder, DRM_MODE_DPMS_ON);
727 cdv_intel_dp_link_down(intel_encoder); 953 cdv_intel_dp_link_down(intel_encoder);
954 if (edp)
955 cdv_intel_edp_panel_vdd_off(intel_encoder);
728} 956}
729 957
730static void cdv_intel_dp_commit(struct drm_encoder *encoder) 958static void cdv_intel_dp_commit(struct drm_encoder *encoder)
731{ 959{
732 struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); 960 struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder);
961 int edp = is_edp(intel_encoder);
733 962
963 if (edp)
964 cdv_intel_edp_panel_on(intel_encoder);
734 cdv_intel_dp_start_link_train(intel_encoder); 965 cdv_intel_dp_start_link_train(intel_encoder);
735 cdv_intel_dp_complete_link_train(intel_encoder); 966 cdv_intel_dp_complete_link_train(intel_encoder);
967 if (edp)
968 cdv_intel_edp_backlight_on(intel_encoder);
736} 969}
737 970
738static void 971static void
@@ -742,16 +975,29 @@ cdv_intel_dp_dpms(struct drm_encoder *encoder, int mode)
742 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; 975 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
743 struct drm_device *dev = encoder->dev; 976 struct drm_device *dev = encoder->dev;
744 uint32_t dp_reg = REG_READ(intel_dp->output_reg); 977 uint32_t dp_reg = REG_READ(intel_dp->output_reg);
978 int edp = is_edp(intel_encoder);
745 979
746 if (mode != DRM_MODE_DPMS_ON) { 980 if (mode != DRM_MODE_DPMS_ON) {
981 if (edp) {
982 cdv_intel_edp_backlight_off(intel_encoder);
983 cdv_intel_edp_panel_vdd_on(intel_encoder);
984 }
747 cdv_intel_dp_sink_dpms(intel_encoder, mode); 985 cdv_intel_dp_sink_dpms(intel_encoder, mode);
748 cdv_intel_dp_link_down(intel_encoder); 986 cdv_intel_dp_link_down(intel_encoder);
987 if (edp) {
988 cdv_intel_edp_panel_vdd_off(intel_encoder);
989 cdv_intel_edp_panel_off(intel_encoder);
990 }
749 } else { 991 } else {
992 if (edp)
993 cdv_intel_edp_panel_on(intel_encoder);
750 cdv_intel_dp_sink_dpms(intel_encoder, mode); 994 cdv_intel_dp_sink_dpms(intel_encoder, mode);
751 if (!(dp_reg & DP_PORT_EN)) { 995 if (!(dp_reg & DP_PORT_EN)) {
752 cdv_intel_dp_start_link_train(intel_encoder); 996 cdv_intel_dp_start_link_train(intel_encoder);
753 cdv_intel_dp_complete_link_train(intel_encoder); 997 cdv_intel_dp_complete_link_train(intel_encoder);
754 } 998 }
999 if (edp)
1000 cdv_intel_edp_backlight_on(intel_encoder);
755 } 1001 }
756} 1002}
757 1003
@@ -1090,6 +1336,10 @@ cdv_intel_dp_start_link_train(struct psb_intel_encoder *encoder)
1090 1336
1091 for (;;) { 1337 for (;;) {
1092 /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ 1338 /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
1339 DRM_DEBUG_KMS("DP Link Train Set %x, Link_config %x, %x\n",
1340 intel_dp->train_set[0],
1341 intel_dp->link_configuration[0],
1342 intel_dp->link_configuration[1]);
1093 1343
1094 if (!cdv_intel_dp_set_link_train(encoder, reg, DP_TRAINING_PATTERN_1)) { 1344 if (!cdv_intel_dp_set_link_train(encoder, reg, DP_TRAINING_PATTERN_1)) {
1095 DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 1\n"); 1345 DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 1\n");
@@ -1103,6 +1353,10 @@ cdv_intel_dp_start_link_train(struct psb_intel_encoder *encoder)
1103 if (!cdv_intel_dp_get_link_status(encoder)) 1353 if (!cdv_intel_dp_get_link_status(encoder))
1104 break; 1354 break;
1105 1355
1356 DRM_DEBUG_KMS("DP Link status %x, %x, %x, %x, %x, %x\n",
1357 intel_dp->link_status[0], intel_dp->link_status[1], intel_dp->link_status[2],
1358 intel_dp->link_status[3], intel_dp->link_status[4], intel_dp->link_status[5]);
1359
1106 if (cdv_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { 1360 if (cdv_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
1107 DRM_DEBUG_KMS("PT1 train is done\n"); 1361 DRM_DEBUG_KMS("PT1 train is done\n");
1108 clock_recovery = true; 1362 clock_recovery = true;
@@ -1156,7 +1410,13 @@ cdv_intel_dp_complete_link_train(struct psb_intel_encoder *encoder)
1156 reg = DP | DP_LINK_TRAIN_PAT_2; 1410 reg = DP | DP_LINK_TRAIN_PAT_2;
1157 1411
1158 for (;;) { 1412 for (;;) {
1159 /* channel eq pattern */ 1413
1414 DRM_DEBUG_KMS("DP Link Train Set %x, Link_config %x, %x\n",
1415 intel_dp->train_set[0],
1416 intel_dp->link_configuration[0],
1417 intel_dp->link_configuration[1]);
1418 /* channel eq pattern */
1419
1160 if (!cdv_intel_dp_set_link_train(encoder, reg, 1420 if (!cdv_intel_dp_set_link_train(encoder, reg,
1161 DP_TRAINING_PATTERN_2)) { 1421 DP_TRAINING_PATTERN_2)) {
1162 DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 2\n"); 1422 DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 2\n");
@@ -1177,6 +1437,10 @@ cdv_intel_dp_complete_link_train(struct psb_intel_encoder *encoder)
1177 if (!cdv_intel_dp_get_link_status(encoder)) 1437 if (!cdv_intel_dp_get_link_status(encoder))
1178 break; 1438 break;
1179 1439
1440 DRM_DEBUG_KMS("DP Link status %x, %x, %x, %x, %x, %x\n",
1441 intel_dp->link_status[0], intel_dp->link_status[1], intel_dp->link_status[2],
1442 intel_dp->link_status[3], intel_dp->link_status[4], intel_dp->link_status[5]);
1443
1180 /* Make sure clock is still ok */ 1444 /* Make sure clock is still ok */
1181 if (!cdv_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { 1445 if (!cdv_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
1182 cdv_intel_dp_start_link_train(encoder); 1446 cdv_intel_dp_start_link_train(encoder);
@@ -1271,12 +1535,18 @@ cdv_intel_dp_detect(struct drm_connector *connector, bool force)
1271 struct cdv_intel_dp *intel_dp = encoder->dev_priv; 1535 struct cdv_intel_dp *intel_dp = encoder->dev_priv;
1272 enum drm_connector_status status; 1536 enum drm_connector_status status;
1273 struct edid *edid = NULL; 1537 struct edid *edid = NULL;
1538 int edp = is_edp(encoder);
1274 1539
1275 intel_dp->has_audio = false; 1540 intel_dp->has_audio = false;
1276 1541
1542 if (edp)
1543 cdv_intel_edp_panel_vdd_on(encoder);
1277 status = cdv_dp_detect(encoder); 1544 status = cdv_dp_detect(encoder);
1278 if (status != connector_status_connected) 1545 if (status != connector_status_connected) {
1546 if (edp)
1547 cdv_intel_edp_panel_vdd_off(encoder);
1279 return status; 1548 return status;
1549 }
1280 1550
1281 if (intel_dp->force_audio) { 1551 if (intel_dp->force_audio) {
1282 intel_dp->has_audio = intel_dp->force_audio > 0; 1552 intel_dp->has_audio = intel_dp->force_audio > 0;
@@ -1288,6 +1558,8 @@ cdv_intel_dp_detect(struct drm_connector *connector, bool force)
1288 kfree(edid); 1558 kfree(edid);
1289 } 1559 }
1290 } 1560 }
1561 if (edp)
1562 cdv_intel_edp_panel_vdd_off(encoder);
1291 1563
1292 return connector_status_connected; 1564 return connector_status_connected;
1293} 1565}
@@ -1298,6 +1570,7 @@ static int cdv_intel_dp_get_modes(struct drm_connector *connector)
1298 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; 1570 struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv;
1299 struct edid *edid = NULL; 1571 struct edid *edid = NULL;
1300 int ret = 0; 1572 int ret = 0;
1573 int edp = is_edp(intel_encoder);
1301 1574
1302 1575
1303 edid = drm_get_edid(connector, &intel_dp->adapter); 1576 edid = drm_get_edid(connector, &intel_dp->adapter);
@@ -1307,6 +1580,42 @@ static int cdv_intel_dp_get_modes(struct drm_connector *connector)
1307 kfree(edid); 1580 kfree(edid);
1308 } 1581 }
1309 1582
1583 if (is_edp(intel_encoder)) {
1584 struct drm_device *dev = connector->dev;
1585 struct drm_psb_private *dev_priv = dev->dev_private;
1586
1587 cdv_intel_edp_panel_vdd_off(intel_encoder);
1588 if (ret) {
1589 if (edp && !intel_dp->panel_fixed_mode) {
1590 struct drm_display_mode *newmode;
1591 list_for_each_entry(newmode, &connector->probed_modes,
1592 head) {
1593 if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
1594 intel_dp->panel_fixed_mode =
1595 drm_mode_duplicate(dev, newmode);
1596 break;
1597 }
1598 }
1599 }
1600
1601 return ret;
1602 }
1603 if (!intel_dp->panel_fixed_mode && dev_priv->lfp_lvds_vbt_mode) {
1604 intel_dp->panel_fixed_mode =
1605 drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
1606 if (intel_dp->panel_fixed_mode) {
1607 intel_dp->panel_fixed_mode->type |=
1608 DRM_MODE_TYPE_PREFERRED;
1609 }
1610 }
1611 if (intel_dp->panel_fixed_mode != NULL) {
1612 struct drm_display_mode *mode;
1613 mode = drm_mode_duplicate(dev, intel_dp->panel_fixed_mode);
1614 drm_mode_probed_add(connector, mode);
1615 return 1;
1616 }
1617 }
1618
1310 return ret; 1619 return ret;
1311} 1620}
1312 1621
@@ -1317,6 +1626,10 @@ cdv_intel_dp_detect_audio(struct drm_connector *connector)
1317 struct cdv_intel_dp *intel_dp = encoder->dev_priv; 1626 struct cdv_intel_dp *intel_dp = encoder->dev_priv;
1318 struct edid *edid; 1627 struct edid *edid;
1319 bool has_audio = false; 1628 bool has_audio = false;
1629 int edp = is_edp(encoder);
1630
1631 if (edp)
1632 cdv_intel_edp_panel_vdd_on(encoder);
1320 1633
1321 edid = drm_get_edid(connector, &intel_dp->adapter); 1634 edid = drm_get_edid(connector, &intel_dp->adapter);
1322 if (edid) { 1635 if (edid) {
@@ -1325,6 +1638,8 @@ cdv_intel_dp_detect_audio(struct drm_connector *connector)
1325 connector->display_info.raw_edid = NULL; 1638 connector->display_info.raw_edid = NULL;
1326 kfree(edid); 1639 kfree(edid);
1327 } 1640 }
1641 if (edp)
1642 cdv_intel_edp_panel_vdd_off(encoder);
1328 1643
1329 return has_audio; 1644 return has_audio;
1330} 1645}
@@ -1386,12 +1701,19 @@ done:
1386} 1701}
1387 1702
1388static void 1703static void
1389cdv_intel_dp_destroy (struct drm_connector *connector) 1704cdv_intel_dp_destroy(struct drm_connector *connector)
1390{ 1705{
1391 struct psb_intel_encoder *psb_intel_encoder = 1706 struct psb_intel_encoder *psb_intel_encoder =
1392 psb_intel_attached_encoder(connector); 1707 psb_intel_attached_encoder(connector);
1393 struct cdv_intel_dp *intel_dp = psb_intel_encoder->dev_priv; 1708 struct cdv_intel_dp *intel_dp = psb_intel_encoder->dev_priv;
1394 1709
1710 if (is_edp(psb_intel_encoder)) {
1711 /* cdv_intel_panel_destroy_backlight(connector->dev); */
1712 if (intel_dp->panel_fixed_mode) {
1713 kfree(intel_dp->panel_fixed_mode);
1714 intel_dp->panel_fixed_mode = NULL;
1715 }
1716 }
1395 i2c_del_adapter(&intel_dp->adapter); 1717 i2c_del_adapter(&intel_dp->adapter);
1396 drm_sysfs_connector_remove(connector); 1718 drm_sysfs_connector_remove(connector);
1397 drm_connector_cleanup(connector); 1719 drm_connector_cleanup(connector);
@@ -1436,6 +1758,26 @@ static void cdv_intel_dp_add_properties(struct drm_connector *connector)
1436 cdv_intel_attach_broadcast_rgb_property(connector); 1758 cdv_intel_attach_broadcast_rgb_property(connector);
1437} 1759}
1438 1760
1761/* check the VBT to see whether the eDP is on DP-D port */
1762static bool cdv_intel_dpc_is_edp(struct drm_device *dev)
1763{
1764 struct drm_psb_private *dev_priv = dev->dev_private;
1765 struct child_device_config *p_child;
1766 int i;
1767
1768 if (!dev_priv->child_dev_num)
1769 return false;
1770
1771 for (i = 0; i < dev_priv->child_dev_num; i++) {
1772 p_child = dev_priv->child_dev + i;
1773
1774 if (p_child->dvo_port == PORT_IDPC &&
1775 p_child->device_type == DEVICE_TYPE_eDP)
1776 return true;
1777 }
1778 return false;
1779}
1780
1439void 1781void
1440cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int output_reg) 1782cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int output_reg)
1441{ 1783{
@@ -1445,6 +1787,7 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev
1445 struct drm_encoder *encoder; 1787 struct drm_encoder *encoder;
1446 struct cdv_intel_dp *intel_dp; 1788 struct cdv_intel_dp *intel_dp;
1447 const char *name = NULL; 1789 const char *name = NULL;
1790 int type = DRM_MODE_CONNECTOR_DisplayPort;
1448 1791
1449 psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL); 1792 psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
1450 if (!psb_intel_encoder) 1793 if (!psb_intel_encoder)
@@ -1456,14 +1799,22 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev
1456 if (!intel_dp) 1799 if (!intel_dp)
1457 goto err_priv; 1800 goto err_priv;
1458 1801
1802 if ((output_reg == DP_C) && cdv_intel_dpc_is_edp(dev))
1803 type = DRM_MODE_CONNECTOR_eDP;
1804
1459 connector = &psb_intel_connector->base; 1805 connector = &psb_intel_connector->base;
1460 encoder = &psb_intel_encoder->base; 1806 encoder = &psb_intel_encoder->base;
1461 1807
1462 drm_connector_init(dev, connector, &cdv_intel_dp_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); 1808 drm_connector_init(dev, connector, &cdv_intel_dp_connector_funcs, type);
1463 drm_encoder_init(dev, encoder, &cdv_intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS); 1809 drm_encoder_init(dev, encoder, &cdv_intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS);
1464 1810
1465 psb_intel_connector_attach_encoder(psb_intel_connector, psb_intel_encoder); 1811 psb_intel_connector_attach_encoder(psb_intel_connector, psb_intel_encoder);
1466 psb_intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; 1812
1813 if (type == DRM_MODE_CONNECTOR_DisplayPort)
1814 psb_intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
1815 else
1816 psb_intel_encoder->type = INTEL_OUTPUT_EDP;
1817
1467 1818
1468 psb_intel_encoder->dev_priv=intel_dp; 1819 psb_intel_encoder->dev_priv=intel_dp;
1469 intel_dp->encoder = psb_intel_encoder; 1820 intel_dp->encoder = psb_intel_encoder;
@@ -1493,6 +1844,83 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev
1493 cdv_intel_dp_i2c_init(psb_intel_connector, psb_intel_encoder, name); 1844 cdv_intel_dp_i2c_init(psb_intel_connector, psb_intel_encoder, name);
1494 /* FIXME:fail check */ 1845 /* FIXME:fail check */
1495 cdv_intel_dp_add_properties(connector); 1846 cdv_intel_dp_add_properties(connector);
1847
1848 if (is_edp(psb_intel_encoder)) {
1849 int ret;
1850 struct edp_power_seq cur;
1851 u32 pp_on, pp_off, pp_div;
1852 u32 pwm_ctrl;
1853
1854 pp_on = REG_READ(PP_CONTROL);
1855 pp_on &= ~PANEL_UNLOCK_MASK;
1856 pp_on |= PANEL_UNLOCK_REGS;
1857
1858 REG_WRITE(PP_CONTROL, pp_on);
1859
1860 pwm_ctrl = REG_READ(BLC_PWM_CTL2);
1861 pwm_ctrl |= PWM_PIPE_B;
1862 REG_WRITE(BLC_PWM_CTL2, pwm_ctrl);
1863
1864 pp_on = REG_READ(PP_ON_DELAYS);
1865 pp_off = REG_READ(PP_OFF_DELAYS);
1866 pp_div = REG_READ(PP_DIVISOR);
1867
1868 /* Pull timing values out of registers */
1869 cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >>
1870 PANEL_POWER_UP_DELAY_SHIFT;
1871
1872 cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >>
1873 PANEL_LIGHT_ON_DELAY_SHIFT;
1874
1875 cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >>
1876 PANEL_LIGHT_OFF_DELAY_SHIFT;
1877
1878 cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >>
1879 PANEL_POWER_DOWN_DELAY_SHIFT;
1880
1881 cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
1882 PANEL_POWER_CYCLE_DELAY_SHIFT);
1883
1884 DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
1885 cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12);
1886
1887
1888 intel_dp->panel_power_up_delay = cur.t1_t3 / 10;
1889 intel_dp->backlight_on_delay = cur.t8 / 10;
1890 intel_dp->backlight_off_delay = cur.t9 / 10;
1891 intel_dp->panel_power_down_delay = cur.t10 / 10;
1892 intel_dp->panel_power_cycle_delay = (cur.t11_t12 - 1) * 100;
1893
1894 DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n",
1895 intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay,
1896 intel_dp->panel_power_cycle_delay);
1897
1898 DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
1899 intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
1900
1901
1902 cdv_intel_edp_panel_vdd_on(psb_intel_encoder);
1903 ret = cdv_intel_dp_aux_native_read(psb_intel_encoder, DP_DPCD_REV,
1904 intel_dp->dpcd,
1905 sizeof(intel_dp->dpcd));
1906 cdv_intel_edp_panel_vdd_off(psb_intel_encoder);
1907 if (ret == 0) {
1908 /* if this fails, presume the device is a ghost */
1909 DRM_INFO("failed to retrieve link info, disabling eDP\n");
1910 cdv_intel_dp_encoder_destroy(encoder);
1911 cdv_intel_dp_destroy(connector);
1912 goto err_priv;
1913 } else {
1914 DRM_DEBUG_KMS("DPCD: Rev=%x LN_Rate=%x LN_CNT=%x LN_DOWNSP=%x\n",
1915 intel_dp->dpcd[0], intel_dp->dpcd[1],
1916 intel_dp->dpcd[2], intel_dp->dpcd[3]);
1917
1918 }
1919 /* The CDV reference driver moves pnale backlight setup into the displays that
1920 have a backlight: this is a good idea and one we should probably adopt, however
1921 we need to migrate all the drivers before we can do that */
1922 /*cdv_intel_panel_setup_backlight(dev); */
1923 }
1496 return; 1924 return;
1497 1925
1498err_priv: 1926err_priv:
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index c7f9468b74ba..b362dd39bf5a 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -506,16 +506,8 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector,
506 property, 506 property,
507 value)) 507 value))
508 return -1; 508 return -1;
509 else { 509 else
510#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 510 gma_backlight_set(encoder->dev, value);
511 struct drm_psb_private *dev_priv =
512 encoder->dev->dev_private;
513 struct backlight_device *bd =
514 dev_priv->backlight_device;
515 bd->props.brightness = value;
516 backlight_update_status(bd);
517#endif
518 }
519 } else if (!strcmp(property->name, "DPMS") && encoder) { 511 } else if (!strcmp(property->name, "DPMS") && encoder) {
520 struct drm_encoder_helper_funcs *helpers = 512 struct drm_encoder_helper_funcs *helpers =
521 encoder->helper_private; 513 encoder->helper_private;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 2de6b1fcc135..884ba73ac6ce 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -768,6 +768,9 @@ static void psb_setup_outputs(struct drm_device *dev)
768 crtc_mask = (1 << 0) | (1 << 1); 768 crtc_mask = (1 << 0) | (1 << 1);
769 clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); 769 clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
770 break; 770 break;
771 case INTEL_OUTPUT_EDP:
772 crtc_mask = (1 << 1);
773 clone_mask = (1 << INTEL_OUTPUT_EDP);
771 } 774 }
772 encoder->possible_crtcs = crtc_mask; 775 encoder->possible_crtcs = crtc_mask;
773 encoder->possible_clones = 776 encoder->possible_clones =
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c
index 8d7caf0f363e..4fb79cf00ed8 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -54,6 +54,98 @@ static void *find_section(struct bdb_header *bdb, int section_id)
54 return NULL; 54 return NULL;
55} 55}
56 56
57static void
58parse_edp(struct drm_psb_private *dev_priv, struct bdb_header *bdb)
59{
60 struct bdb_edp *edp;
61 struct edp_power_seq *edp_pps;
62 struct edp_link_params *edp_link_params;
63 uint8_t panel_type;
64
65 edp = find_section(bdb, BDB_EDP);
66
67 dev_priv->edp.bpp = 18;
68 if (!edp) {
69 if (dev_priv->edp.support) {
70 DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported, assume %dbpp panel color depth.\n",
71 dev_priv->edp.bpp);
72 }
73 return;
74 }
75
76 panel_type = dev_priv->panel_type;
77 switch ((edp->color_depth >> (panel_type * 2)) & 3) {
78 case EDP_18BPP:
79 dev_priv->edp.bpp = 18;
80 break;
81 case EDP_24BPP:
82 dev_priv->edp.bpp = 24;
83 break;
84 case EDP_30BPP:
85 dev_priv->edp.bpp = 30;
86 break;
87 }
88
89 /* Get the eDP sequencing and link info */
90 edp_pps = &edp->power_seqs[panel_type];
91 edp_link_params = &edp->link_params[panel_type];
92
93 dev_priv->edp.pps = *edp_pps;
94
95 DRM_DEBUG_KMS("EDP timing in vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
96 dev_priv->edp.pps.t1_t3, dev_priv->edp.pps.t8,
97 dev_priv->edp.pps.t9, dev_priv->edp.pps.t10,
98 dev_priv->edp.pps.t11_t12);
99
100 dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
101 DP_LINK_BW_1_62;
102 switch (edp_link_params->lanes) {
103 case 0:
104 dev_priv->edp.lanes = 1;
105 break;
106 case 1:
107 dev_priv->edp.lanes = 2;
108 break;
109 case 3:
110 default:
111 dev_priv->edp.lanes = 4;
112 break;
113 }
114 DRM_DEBUG_KMS("VBT reports EDP: Lane_count %d, Lane_rate %d, Bpp %d\n",
115 dev_priv->edp.lanes, dev_priv->edp.rate, dev_priv->edp.bpp);
116
117 switch (edp_link_params->preemphasis) {
118 case 0:
119 dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
120 break;
121 case 1:
122 dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
123 break;
124 case 2:
125 dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
126 break;
127 case 3:
128 dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
129 break;
130 }
131 switch (edp_link_params->vswing) {
132 case 0:
133 dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_400;
134 break;
135 case 1:
136 dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_600;
137 break;
138 case 2:
139 dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_800;
140 break;
141 case 3:
142 dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_1200;
143 break;
144 }
145 DRM_DEBUG_KMS("VBT reports EDP: VSwing %d, Preemph %d\n",
146 dev_priv->edp.vswing, dev_priv->edp.preemphasis);
147}
148
57static u16 149static u16
58get_blocksize(void *p) 150get_blocksize(void *p)
59{ 151{
@@ -154,6 +246,8 @@ static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,
154 return; 246 return;
155 247
156 dev_priv->lvds_dither = lvds_options->pixel_dither; 248 dev_priv->lvds_dither = lvds_options->pixel_dither;
249 dev_priv->panel_type = lvds_options->panel_type;
250
157 if (lvds_options->panel_type == 0xff) 251 if (lvds_options->panel_type == 0xff)
158 return; 252 return;
159 253
@@ -340,6 +434,9 @@ parse_driver_features(struct drm_psb_private *dev_priv,
340 if (!driver) 434 if (!driver)
341 return; 435 return;
342 436
437 if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
438 dev_priv->edp.support = 1;
439
343 /* This bit means to use 96Mhz for DPLL_A or not */ 440 /* This bit means to use 96Mhz for DPLL_A or not */
344 if (driver->primary_lfp_id) 441 if (driver->primary_lfp_id)
345 dev_priv->dplla_96mhz = true; 442 dev_priv->dplla_96mhz = true;
@@ -437,6 +534,9 @@ int psb_intel_init_bios(struct drm_device *dev)
437 size_t size; 534 size_t size;
438 int i; 535 int i;
439 536
537
538 dev_priv->panel_type = 0xff;
539
440 /* XXX Should this validation be moved to intel_opregion.c? */ 540 /* XXX Should this validation be moved to intel_opregion.c? */
441 if (dev_priv->opregion.vbt) { 541 if (dev_priv->opregion.vbt) {
442 struct vbt_header *vbt = dev_priv->opregion.vbt; 542 struct vbt_header *vbt = dev_priv->opregion.vbt;
@@ -477,6 +577,7 @@ int psb_intel_init_bios(struct drm_device *dev)
477 parse_sdvo_device_mapping(dev_priv, bdb); 577 parse_sdvo_device_mapping(dev_priv, bdb);
478 parse_device_mapping(dev_priv, bdb); 578 parse_device_mapping(dev_priv, bdb);
479 parse_backlight_data(dev_priv, bdb); 579 parse_backlight_data(dev_priv, bdb);
580 parse_edp(dev_priv, bdb);
480 581
481 if (bios) 582 if (bios)
482 pci_unmap_rom(pdev, bios); 583 pci_unmap_rom(pdev, bios);
diff --git a/drivers/gpu/drm/gma500/intel_bios.h b/drivers/gpu/drm/gma500/intel_bios.h
index 2e95523b84b1..c6267c98c9e7 100644
--- a/drivers/gpu/drm/gma500/intel_bios.h
+++ b/drivers/gpu/drm/gma500/intel_bios.h
@@ -23,6 +23,7 @@
23#define _I830_BIOS_H_ 23#define _I830_BIOS_H_
24 24
25#include <drm/drmP.h> 25#include <drm/drmP.h>
26#include <drm/drm_dp_helper.h>
26 27
27struct vbt_header { 28struct vbt_header {
28 u8 signature[20]; /**< Always starts with 'VBT$' */ 29 u8 signature[20]; /**< Always starts with 'VBT$' */
@@ -93,6 +94,7 @@ struct vbios_data {
93#define BDB_SDVO_LVDS_PNP_IDS 24 94#define BDB_SDVO_LVDS_PNP_IDS 24
94#define BDB_SDVO_LVDS_POWER_SEQ 25 95#define BDB_SDVO_LVDS_POWER_SEQ 25
95#define BDB_TV_OPTIONS 26 96#define BDB_TV_OPTIONS 26
97#define BDB_EDP 27
96#define BDB_LVDS_OPTIONS 40 98#define BDB_LVDS_OPTIONS 40
97#define BDB_LVDS_LFP_DATA_PTRS 41 99#define BDB_LVDS_LFP_DATA_PTRS 41
98#define BDB_LVDS_LFP_DATA 42 100#define BDB_LVDS_LFP_DATA 42
@@ -391,6 +393,11 @@ struct bdb_sdvo_lvds_options {
391 u8 panel_misc_bits_4; 393 u8 panel_misc_bits_4;
392} __attribute__((packed)); 394} __attribute__((packed));
393 395
396#define BDB_DRIVER_FEATURE_NO_LVDS 0
397#define BDB_DRIVER_FEATURE_INT_LVDS 1
398#define BDB_DRIVER_FEATURE_SDVO_LVDS 2
399#define BDB_DRIVER_FEATURE_EDP 3
400
394struct bdb_driver_features { 401struct bdb_driver_features {
395 u8 boot_dev_algorithm:1; 402 u8 boot_dev_algorithm:1;
396 u8 block_display_switch:1; 403 u8 block_display_switch:1;
@@ -431,6 +438,45 @@ struct bdb_driver_features {
431 u8 custom_vbt_version; 438 u8 custom_vbt_version;
432} __attribute__((packed)); 439} __attribute__((packed));
433 440
441#define EDP_18BPP 0
442#define EDP_24BPP 1
443#define EDP_30BPP 2
444#define EDP_RATE_1_62 0
445#define EDP_RATE_2_7 1
446#define EDP_LANE_1 0
447#define EDP_LANE_2 1
448#define EDP_LANE_4 3
449#define EDP_PREEMPHASIS_NONE 0
450#define EDP_PREEMPHASIS_3_5dB 1
451#define EDP_PREEMPHASIS_6dB 2
452#define EDP_PREEMPHASIS_9_5dB 3
453#define EDP_VSWING_0_4V 0
454#define EDP_VSWING_0_6V 1
455#define EDP_VSWING_0_8V 2
456#define EDP_VSWING_1_2V 3
457
458struct edp_power_seq {
459 u16 t1_t3;
460 u16 t8;
461 u16 t9;
462 u16 t10;
463 u16 t11_t12;
464} __attribute__ ((packed));
465
466struct edp_link_params {
467 u8 rate:4;
468 u8 lanes:4;
469 u8 preemphasis:4;
470 u8 vswing:4;
471} __attribute__ ((packed));
472
473struct bdb_edp {
474 struct edp_power_seq power_seqs[16];
475 u32 color_depth;
476 u32 sdrrs_msa_timing_delay;
477 struct edp_link_params link_params[16];
478} __attribute__ ((packed));
479
434extern int psb_intel_init_bios(struct drm_device *dev); 480extern int psb_intel_init_bios(struct drm_device *dev);
435extern void psb_intel_destroy_bios(struct drm_device *dev); 481extern void psb_intel_destroy_bios(struct drm_device *dev);
436 482
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
index 5675d93b4205..32dba2ab53e1 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
@@ -299,17 +299,8 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
299 if (drm_connector_property_set_value(connector, property, 299 if (drm_connector_property_set_value(connector, property,
300 value)) 300 value))
301 goto set_prop_error; 301 goto set_prop_error;
302 else { 302 else
303#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 303 gma_backlight_set(encoder->dev, value);
304 struct backlight_device *psb_bd;
305
306 psb_bd = mdfld_get_backlight_device();
307 if (psb_bd) {
308 psb_bd->props.brightness = value;
309 mdfld_set_brightness(psb_bd);
310 }
311#endif
312 }
313 } 304 }
314set_prop_done: 305set_prop_done:
315 return 0; 306 return 0;
diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c
index b2a790bd9899..850cd3fbb969 100644
--- a/drivers/gpu/drm/gma500/mid_bios.c
+++ b/drivers/gpu/drm/gma500/mid_bios.c
@@ -118,20 +118,20 @@ static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
118 dev_priv->platform_rev_id); 118 dev_priv->platform_rev_id);
119} 119}
120 120
121struct vbt_header { 121struct mid_vbt_header {
122 u32 signature; 122 u32 signature;
123 u8 revision; 123 u8 revision;
124} __packed; 124} __packed;
125 125
126/* The same for r0 and r1 */ 126/* The same for r0 and r1 */
127struct vbt_r0 { 127struct vbt_r0 {
128 struct vbt_header vbt_header; 128 struct mid_vbt_header vbt_header;
129 u8 size; 129 u8 size;
130 u8 checksum; 130 u8 checksum;
131} __packed; 131} __packed;
132 132
133struct vbt_r10 { 133struct vbt_r10 {
134 struct vbt_header vbt_header; 134 struct mid_vbt_header vbt_header;
135 u8 checksum; 135 u8 checksum;
136 u16 size; 136 u16 size;
137 u8 panel_count; 137 u8 panel_count;
@@ -281,7 +281,7 @@ static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
281 struct drm_device *dev = dev_priv->dev; 281 struct drm_device *dev = dev_priv->dev;
282 u32 addr; 282 u32 addr;
283 u8 __iomem *vbt_virtual; 283 u8 __iomem *vbt_virtual;
284 struct vbt_header vbt_header; 284 struct mid_vbt_header vbt_header;
285 struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); 285 struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
286 int ret = -1; 286 int ret = -1;
287 287
diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c
index c430bd424681..ad0d6de938f3 100644
--- a/drivers/gpu/drm/gma500/opregion.c
+++ b/drivers/gpu/drm/gma500/opregion.c
@@ -166,8 +166,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
166 166
167 if (config_enabled(CONFIG_BACKLIGHT_CLASS_DEVICE)) { 167 if (config_enabled(CONFIG_BACKLIGHT_CLASS_DEVICE)) {
168 int max = bd->props.max_brightness; 168 int max = bd->props.max_brightness;
169 bd->props.brightness = bclp * max / 255; 169 gma_backlight_set(dev, bclp * max / 255);
170 backlight_update_status(bd);
171 } 170 }
172 171
173 asle->cblv = (bclp * 0x64) / 0xff | ASLE_CBLV_VALID; 172 asle->cblv = (bclp * 0x64) / 0xff | ASLE_CBLV_VALID;
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 1bd115ecefe1..4ab6ae7e92b4 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -28,6 +28,7 @@
28#include "gma_drm.h" 28#include "gma_drm.h"
29#include "psb_reg.h" 29#include "psb_reg.h"
30#include "psb_intel_drv.h" 30#include "psb_intel_drv.h"
31#include "intel_bios.h"
31#include "gtt.h" 32#include "gtt.h"
32#include "power.h" 33#include "power.h"
33#include "opregion.h" 34#include "opregion.h"
@@ -613,6 +614,8 @@ struct drm_psb_private {
613 */ 614 */
614 struct backlight_device *backlight_device; 615 struct backlight_device *backlight_device;
615 struct drm_property *backlight_property; 616 struct drm_property *backlight_property;
617 bool backlight_enabled;
618 int backlight_level;
616 uint32_t blc_adj1; 619 uint32_t blc_adj1;
617 uint32_t blc_adj2; 620 uint32_t blc_adj2;
618 621
@@ -640,6 +643,19 @@ struct drm_psb_private {
640 int mdfld_panel_id; 643 int mdfld_panel_id;
641 644
642 bool dplla_96mhz; /* DPLL data from the VBT */ 645 bool dplla_96mhz; /* DPLL data from the VBT */
646
647 struct {
648 int rate;
649 int lanes;
650 int preemphasis;
651 int vswing;
652
653 bool initialized;
654 bool support;
655 int bpp;
656 struct edp_power_seq pps;
657 } edp;
658 uint8_t panel_type;
643}; 659};
644 660
645 661
@@ -796,6 +812,9 @@ extern int psb_fbdev_init(struct drm_device *dev);
796/* backlight.c */ 812/* backlight.c */
797int gma_backlight_init(struct drm_device *dev); 813int gma_backlight_init(struct drm_device *dev);
798void gma_backlight_exit(struct drm_device *dev); 814void gma_backlight_exit(struct drm_device *dev);
815void gma_backlight_disable(struct drm_device *dev);
816void gma_backlight_enable(struct drm_device *dev);
817void gma_backlight_set(struct drm_device *dev, int v);
799 818
800/* oaktrail_crtc.c */ 819/* oaktrail_crtc.c */
801extern const struct drm_crtc_helper_funcs oaktrail_helper_funcs; 820extern const struct drm_crtc_helper_funcs oaktrail_helper_funcs;
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
index 37adc9edf974..2a4c3a9e33e3 100644
--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -630,17 +630,8 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
630 property, 630 property,
631 value)) 631 value))
632 goto set_prop_error; 632 goto set_prop_error;
633 else { 633 else
634#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 634 gma_backlight_set(encoder->dev, value);
635 struct drm_psb_private *devp =
636 encoder->dev->dev_private;
637 struct backlight_device *bd = devp->backlight_device;
638 if (bd) {
639 bd->props.brightness = value;
640 backlight_update_status(bd);
641 }
642#endif
643 }
644 } else if (!strcmp(property->name, "DPMS")) { 635 } else if (!strcmp(property->name, "DPMS")) {
645 struct drm_encoder_helper_funcs *hfuncs 636 struct drm_encoder_helper_funcs *hfuncs
646 = encoder->helper_private; 637 = encoder->helper_private;
diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h
index d3091fc72b9e..389e969e8986 100644
--- a/drivers/gpu/drm/gma500/psb_intel_reg.h
+++ b/drivers/gpu/drm/gma500/psb_intel_reg.h
@@ -173,15 +173,46 @@
173#define PP_SEQUENCE_ON (1 << 28) 173#define PP_SEQUENCE_ON (1 << 28)
174#define PP_SEQUENCE_OFF (2 << 28) 174#define PP_SEQUENCE_OFF (2 << 28)
175#define PP_SEQUENCE_MASK 0x30000000 175#define PP_SEQUENCE_MASK 0x30000000
176#define PP_CYCLE_DELAY_ACTIVE (1 << 27)
177#define PP_SEQUENCE_STATE_ON_IDLE (1 << 3)
178#define PP_SEQUENCE_STATE_MASK 0x0000000f
179
176#define PP_CONTROL 0x61204 180#define PP_CONTROL 0x61204
177#define POWER_TARGET_ON (1 << 0) 181#define POWER_TARGET_ON (1 << 0)
178 182#define PANEL_UNLOCK_REGS (0xabcd << 16)
183#define PANEL_UNLOCK_MASK (0xffff << 16)
184#define EDP_FORCE_VDD (1 << 3)
185#define EDP_BLC_ENABLE (1 << 2)
186#define PANEL_POWER_RESET (1 << 1)
187#define PANEL_POWER_OFF (0 << 0)
188#define PANEL_POWER_ON (1 << 0)
189
190/* Poulsbo/Oaktrail */
179#define LVDSPP_ON 0x61208 191#define LVDSPP_ON 0x61208
180#define LVDSPP_OFF 0x6120c 192#define LVDSPP_OFF 0x6120c
181#define PP_CYCLE 0x61210 193#define PP_CYCLE 0x61210
182 194
195/* Cedartrail */
183#define PP_ON_DELAYS 0x61208 /* Cedartrail */ 196#define PP_ON_DELAYS 0x61208 /* Cedartrail */
197#define PANEL_PORT_SELECT_MASK (3 << 30)
198#define PANEL_PORT_SELECT_LVDS (0 << 30)
199#define PANEL_PORT_SELECT_EDP (1 << 30)
200#define PANEL_POWER_UP_DELAY_MASK (0x1fff0000)
201#define PANEL_POWER_UP_DELAY_SHIFT 16
202#define PANEL_LIGHT_ON_DELAY_MASK (0x1fff)
203#define PANEL_LIGHT_ON_DELAY_SHIFT 0
204
184#define PP_OFF_DELAYS 0x6120c /* Cedartrail */ 205#define PP_OFF_DELAYS 0x6120c /* Cedartrail */
206#define PANEL_POWER_DOWN_DELAY_MASK (0x1fff0000)
207#define PANEL_POWER_DOWN_DELAY_SHIFT 16
208#define PANEL_LIGHT_OFF_DELAY_MASK (0x1fff)
209#define PANEL_LIGHT_OFF_DELAY_SHIFT 0
210
211#define PP_DIVISOR 0x61210 /* Cedartrail */
212#define PP_REFERENCE_DIVIDER_MASK (0xffffff00)
213#define PP_REFERENCE_DIVIDER_SHIFT 8
214#define PANEL_POWER_CYCLE_DELAY_MASK (0x1f)
215#define PANEL_POWER_CYCLE_DELAY_SHIFT 0
185 216
186#define PFIT_CONTROL 0x61230 217#define PFIT_CONTROL 0x61230
187#define PFIT_ENABLE (1 << 31) 218#define PFIT_ENABLE (1 << 31)
@@ -1503,4 +1534,9 @@ No status bits are changed.
1503#define PIPE_DP_LINK_M(pipe) _PIPE(pipe, _PIPEA_DP_LINK_M, _PIPEB_DP_LINK_M) 1534#define PIPE_DP_LINK_M(pipe) _PIPE(pipe, _PIPEA_DP_LINK_M, _PIPEB_DP_LINK_M)
1504#define PIPE_DP_LINK_N(pipe) _PIPE(pipe, _PIPEA_DP_LINK_N, _PIPEB_DP_LINK_N) 1535#define PIPE_DP_LINK_N(pipe) _PIPE(pipe, _PIPEA_DP_LINK_N, _PIPEB_DP_LINK_N)
1505 1536
1537#define PIPE_BPC_MASK (7 << 5)
1538#define PIPE_8BPC (0 << 5)
1539#define PIPE_10BPC (1 << 5)
1540#define PIPE_6BPC (2 << 5)
1541
1506#endif 1542#endif