diff options
Diffstat (limited to 'drivers/gpu/drm/gma500')
23 files changed, 2674 insertions, 195 deletions
diff --git a/drivers/gpu/drm/gma500/Makefile b/drivers/gpu/drm/gma500/Makefile index abfa2a93f0d0..7a2d40a5c1e1 100644 --- a/drivers/gpu/drm/gma500/Makefile +++ b/drivers/gpu/drm/gma500/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | ccflags-y += -I$(srctree)/include/drm | 4 | ccflags-y += -I$(srctree)/include/drm |
5 | 5 | ||
6 | gma500_gfx-y += gem_glue.o \ | 6 | gma500_gfx-y += \ |
7 | accel_2d.o \ | 7 | accel_2d.o \ |
8 | backlight.o \ | 8 | backlight.o \ |
9 | framebuffer.o \ | 9 | framebuffer.o \ |
@@ -30,7 +30,8 @@ gma500_gfx-$(CONFIG_DRM_GMA3600) += cdv_device.o \ | |||
30 | cdv_intel_crt.o \ | 30 | cdv_intel_crt.o \ |
31 | cdv_intel_display.o \ | 31 | cdv_intel_display.o \ |
32 | cdv_intel_hdmi.o \ | 32 | cdv_intel_hdmi.o \ |
33 | cdv_intel_lvds.o | 33 | cdv_intel_lvds.o \ |
34 | cdv_intel_dp.o | ||
34 | 35 | ||
35 | gma500_gfx-$(CONFIG_DRM_GMA600) += oaktrail_device.o \ | 36 | gma500_gfx-$(CONFIG_DRM_GMA600) += oaktrail_device.o \ |
36 | oaktrail_crtc.o \ | 37 | oaktrail_crtc.o \ |
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 | ||
29 | static 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 | |||
37 | void 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 | |||
49 | void 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 | |||
61 | void 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 | |||
29 | int gma_backlight_init(struct drm_device *dev) | 73 | int 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 7db0e3bf5a5b..1ceca3d13b65 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c | |||
@@ -58,10 +58,17 @@ static int cdv_output_init(struct drm_device *dev) | |||
58 | cdv_intel_lvds_init(dev, &dev_priv->mode_dev); | 58 | cdv_intel_lvds_init(dev, &dev_priv->mode_dev); |
59 | 59 | ||
60 | /* These bits indicate HDMI not SDVO on CDV */ | 60 | /* These bits indicate HDMI not SDVO on CDV */ |
61 | if (REG_READ(SDVOB) & SDVO_DETECTED) | 61 | if (REG_READ(SDVOB) & SDVO_DETECTED) { |
62 | cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB); | 62 | cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB); |
63 | if (REG_READ(SDVOC) & SDVO_DETECTED) | 63 | if (REG_READ(DP_B) & DP_DETECTED) |
64 | cdv_intel_dp_init(dev, &dev_priv->mode_dev, DP_B); | ||
65 | } | ||
66 | |||
67 | if (REG_READ(SDVOC) & SDVO_DETECTED) { | ||
64 | cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC); | 68 | cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC); |
69 | if (REG_READ(DP_C) & DP_DETECTED) | ||
70 | cdv_intel_dp_init(dev, &dev_priv->mode_dev, DP_C); | ||
71 | } | ||
65 | return 0; | 72 | return 0; |
66 | } | 73 | } |
67 | 74 | ||
@@ -163,6 +170,7 @@ static int cdv_backlight_init(struct drm_device *dev) | |||
163 | cdv_get_brightness(cdv_backlight_device); | 170 | cdv_get_brightness(cdv_backlight_device); |
164 | backlight_update_status(cdv_backlight_device); | 171 | backlight_update_status(cdv_backlight_device); |
165 | dev_priv->backlight_device = cdv_backlight_device; | 172 | dev_priv->backlight_device = cdv_backlight_device; |
173 | dev_priv->backlight_enabled = true; | ||
166 | return 0; | 174 | return 0; |
167 | } | 175 | } |
168 | 176 | ||
@@ -449,6 +457,7 @@ static void cdv_get_core_freq(struct drm_device *dev) | |||
449 | case 6: | 457 | case 6: |
450 | case 7: | 458 | case 7: |
451 | dev_priv->core_freq = 266; | 459 | dev_priv->core_freq = 266; |
460 | break; | ||
452 | default: | 461 | default: |
453 | dev_priv->core_freq = 0; | 462 | dev_priv->core_freq = 0; |
454 | } | 463 | } |
@@ -488,6 +497,65 @@ static void cdv_hotplug_enable(struct drm_device *dev, bool on) | |||
488 | } | 497 | } |
489 | } | 498 | } |
490 | 499 | ||
500 | static const char *force_audio_names[] = { | ||
501 | "off", | ||
502 | "auto", | ||
503 | "on", | ||
504 | }; | ||
505 | |||
506 | void cdv_intel_attach_force_audio_property(struct drm_connector *connector) | ||
507 | { | ||
508 | struct drm_device *dev = connector->dev; | ||
509 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
510 | struct drm_property *prop; | ||
511 | int i; | ||
512 | |||
513 | prop = dev_priv->force_audio_property; | ||
514 | if (prop == NULL) { | ||
515 | prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, | ||
516 | "audio", | ||
517 | ARRAY_SIZE(force_audio_names)); | ||
518 | if (prop == NULL) | ||
519 | return; | ||
520 | |||
521 | for (i = 0; i < ARRAY_SIZE(force_audio_names); i++) | ||
522 | drm_property_add_enum(prop, i, i-1, force_audio_names[i]); | ||
523 | |||
524 | dev_priv->force_audio_property = prop; | ||
525 | } | ||
526 | drm_connector_attach_property(connector, prop, 0); | ||
527 | } | ||
528 | |||
529 | |||
530 | static const char *broadcast_rgb_names[] = { | ||
531 | "Full", | ||
532 | "Limited 16:235", | ||
533 | }; | ||
534 | |||
535 | void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector) | ||
536 | { | ||
537 | struct drm_device *dev = connector->dev; | ||
538 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
539 | struct drm_property *prop; | ||
540 | int i; | ||
541 | |||
542 | prop = dev_priv->broadcast_rgb_property; | ||
543 | if (prop == NULL) { | ||
544 | prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, | ||
545 | "Broadcast RGB", | ||
546 | ARRAY_SIZE(broadcast_rgb_names)); | ||
547 | if (prop == NULL) | ||
548 | return; | ||
549 | |||
550 | for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++) | ||
551 | drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]); | ||
552 | |||
553 | dev_priv->broadcast_rgb_property = prop; | ||
554 | } | ||
555 | |||
556 | drm_connector_attach_property(connector, prop, 0); | ||
557 | } | ||
558 | |||
491 | /* Cedarview */ | 559 | /* Cedarview */ |
492 | static const struct psb_offset cdv_regmap[2] = { | 560 | static const struct psb_offset cdv_regmap[2] = { |
493 | { | 561 | { |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index a68509ba22a8..3cfd0931fbfb 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c | |||
@@ -57,15 +57,26 @@ struct cdv_intel_clock_t { | |||
57 | struct cdv_intel_limit_t { | 57 | struct cdv_intel_limit_t { |
58 | struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1; | 58 | struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1; |
59 | struct cdv_intel_p2_t p2; | 59 | struct cdv_intel_p2_t p2; |
60 | bool (*find_pll)(const struct cdv_intel_limit_t *, struct drm_crtc *, | ||
61 | int, int, struct cdv_intel_clock_t *); | ||
60 | }; | 62 | }; |
61 | 63 | ||
64 | static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit, | ||
65 | struct drm_crtc *crtc, int target, int refclk, | ||
66 | struct cdv_intel_clock_t *best_clock); | ||
67 | static bool cdv_intel_find_dp_pll(const struct cdv_intel_limit_t *limit, struct drm_crtc *crtc, int target, | ||
68 | int refclk, | ||
69 | struct cdv_intel_clock_t *best_clock); | ||
70 | |||
62 | #define CDV_LIMIT_SINGLE_LVDS_96 0 | 71 | #define CDV_LIMIT_SINGLE_LVDS_96 0 |
63 | #define CDV_LIMIT_SINGLE_LVDS_100 1 | 72 | #define CDV_LIMIT_SINGLE_LVDS_100 1 |
64 | #define CDV_LIMIT_DAC_HDMI_27 2 | 73 | #define CDV_LIMIT_DAC_HDMI_27 2 |
65 | #define CDV_LIMIT_DAC_HDMI_96 3 | 74 | #define CDV_LIMIT_DAC_HDMI_96 3 |
75 | #define CDV_LIMIT_DP_27 4 | ||
76 | #define CDV_LIMIT_DP_100 5 | ||
66 | 77 | ||
67 | static const struct cdv_intel_limit_t cdv_intel_limits[] = { | 78 | static const struct cdv_intel_limit_t cdv_intel_limits[] = { |
68 | { /* CDV_SIGNLE_LVDS_96MHz */ | 79 | { /* CDV_SINGLE_LVDS_96MHz */ |
69 | .dot = {.min = 20000, .max = 115500}, | 80 | .dot = {.min = 20000, .max = 115500}, |
70 | .vco = {.min = 1800000, .max = 3600000}, | 81 | .vco = {.min = 1800000, .max = 3600000}, |
71 | .n = {.min = 2, .max = 6}, | 82 | .n = {.min = 2, .max = 6}, |
@@ -76,6 +87,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = { | |||
76 | .p1 = {.min = 2, .max = 10}, | 87 | .p1 = {.min = 2, .max = 10}, |
77 | .p2 = {.dot_limit = 200000, | 88 | .p2 = {.dot_limit = 200000, |
78 | .p2_slow = 14, .p2_fast = 14}, | 89 | .p2_slow = 14, .p2_fast = 14}, |
90 | .find_pll = cdv_intel_find_best_PLL, | ||
79 | }, | 91 | }, |
80 | { /* CDV_SINGLE_LVDS_100MHz */ | 92 | { /* CDV_SINGLE_LVDS_100MHz */ |
81 | .dot = {.min = 20000, .max = 115500}, | 93 | .dot = {.min = 20000, .max = 115500}, |
@@ -90,6 +102,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = { | |||
90 | * is 80-224Mhz. Prefer single channel as much as possible. | 102 | * is 80-224Mhz. Prefer single channel as much as possible. |
91 | */ | 103 | */ |
92 | .p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14}, | 104 | .p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14}, |
105 | .find_pll = cdv_intel_find_best_PLL, | ||
93 | }, | 106 | }, |
94 | { /* CDV_DAC_HDMI_27MHz */ | 107 | { /* CDV_DAC_HDMI_27MHz */ |
95 | .dot = {.min = 20000, .max = 400000}, | 108 | .dot = {.min = 20000, .max = 400000}, |
@@ -101,6 +114,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = { | |||
101 | .p = {.min = 5, .max = 90}, | 114 | .p = {.min = 5, .max = 90}, |
102 | .p1 = {.min = 1, .max = 9}, | 115 | .p1 = {.min = 1, .max = 9}, |
103 | .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5}, | 116 | .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5}, |
117 | .find_pll = cdv_intel_find_best_PLL, | ||
104 | }, | 118 | }, |
105 | { /* CDV_DAC_HDMI_96MHz */ | 119 | { /* CDV_DAC_HDMI_96MHz */ |
106 | .dot = {.min = 20000, .max = 400000}, | 120 | .dot = {.min = 20000, .max = 400000}, |
@@ -112,7 +126,32 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = { | |||
112 | .p = {.min = 5, .max = 100}, | 126 | .p = {.min = 5, .max = 100}, |
113 | .p1 = {.min = 1, .max = 10}, | 127 | .p1 = {.min = 1, .max = 10}, |
114 | .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5}, | 128 | .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5}, |
129 | .find_pll = cdv_intel_find_best_PLL, | ||
130 | }, | ||
131 | { /* CDV_DP_27MHz */ | ||
132 | .dot = {.min = 160000, .max = 272000}, | ||
133 | .vco = {.min = 1809000, .max = 3564000}, | ||
134 | .n = {.min = 1, .max = 1}, | ||
135 | .m = {.min = 67, .max = 132}, | ||
136 | .m1 = {.min = 0, .max = 0}, | ||
137 | .m2 = {.min = 65, .max = 130}, | ||
138 | .p = {.min = 5, .max = 90}, | ||
139 | .p1 = {.min = 1, .max = 9}, | ||
140 | .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10}, | ||
141 | .find_pll = cdv_intel_find_dp_pll, | ||
115 | }, | 142 | }, |
143 | { /* CDV_DP_100MHz */ | ||
144 | .dot = {.min = 160000, .max = 272000}, | ||
145 | .vco = {.min = 1800000, .max = 3600000}, | ||
146 | .n = {.min = 2, .max = 6}, | ||
147 | .m = {.min = 60, .max = 164}, | ||
148 | .m1 = {.min = 0, .max = 0}, | ||
149 | .m2 = {.min = 58, .max = 162}, | ||
150 | .p = {.min = 5, .max = 100}, | ||
151 | .p1 = {.min = 1, .max = 10}, | ||
152 | .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10}, | ||
153 | .find_pll = cdv_intel_find_dp_pll, | ||
154 | } | ||
116 | }; | 155 | }; |
117 | 156 | ||
118 | #define _wait_for(COND, MS, W) ({ \ | 157 | #define _wait_for(COND, MS, W) ({ \ |
@@ -132,7 +171,7 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = { | |||
132 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) | 171 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) |
133 | 172 | ||
134 | 173 | ||
135 | static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val) | 174 | int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val) |
136 | { | 175 | { |
137 | int ret; | 176 | int ret; |
138 | 177 | ||
@@ -159,7 +198,7 @@ static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val) | |||
159 | return 0; | 198 | return 0; |
160 | } | 199 | } |
161 | 200 | ||
162 | static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val) | 201 | int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val) |
163 | { | 202 | { |
164 | int ret; | 203 | int ret; |
165 | static bool dpio_debug = true; | 204 | static bool dpio_debug = true; |
@@ -201,7 +240,7 @@ static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val) | |||
201 | /* Reset the DPIO configuration register. The BIOS does this at every | 240 | /* Reset the DPIO configuration register. The BIOS does this at every |
202 | * mode set. | 241 | * mode set. |
203 | */ | 242 | */ |
204 | static void cdv_sb_reset(struct drm_device *dev) | 243 | void cdv_sb_reset(struct drm_device *dev) |
205 | { | 244 | { |
206 | 245 | ||
207 | REG_WRITE(DPIO_CFG, 0); | 246 | REG_WRITE(DPIO_CFG, 0); |
@@ -216,7 +255,7 @@ static void cdv_sb_reset(struct drm_device *dev) | |||
216 | */ | 255 | */ |
217 | static int | 256 | static int |
218 | cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | 257 | cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, |
219 | struct cdv_intel_clock_t *clock, bool is_lvds) | 258 | struct cdv_intel_clock_t *clock, bool is_lvds, u32 ddi_select) |
220 | { | 259 | { |
221 | struct psb_intel_crtc *psb_crtc = to_psb_intel_crtc(crtc); | 260 | struct psb_intel_crtc *psb_crtc = to_psb_intel_crtc(crtc); |
222 | int pipe = psb_crtc->pipe; | 261 | int pipe = psb_crtc->pipe; |
@@ -259,7 +298,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | |||
259 | ref_value &= ~(REF_CLK_MASK); | 298 | ref_value &= ~(REF_CLK_MASK); |
260 | 299 | ||
261 | /* use DPLL_A for pipeB on CRT/HDMI */ | 300 | /* use DPLL_A for pipeB on CRT/HDMI */ |
262 | if (pipe == 1 && !is_lvds) { | 301 | if (pipe == 1 && !is_lvds && !(ddi_select & DP_MASK)) { |
263 | DRM_DEBUG_KMS("use DPLLA for pipe B\n"); | 302 | DRM_DEBUG_KMS("use DPLLA for pipe B\n"); |
264 | ref_value |= REF_CLK_DPLLA; | 303 | ref_value |= REF_CLK_DPLLA; |
265 | } else { | 304 | } else { |
@@ -336,30 +375,33 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | |||
336 | if (ret) | 375 | if (ret) |
337 | return ret; | 376 | return ret; |
338 | 377 | ||
339 | lane_reg = PSB_LANE0; | 378 | if (ddi_select) { |
340 | cdv_sb_read(dev, lane_reg, &lane_value); | 379 | if ((ddi_select & DDI_MASK) == DDI0_SELECT) { |
341 | lane_value &= ~(LANE_PLL_MASK); | 380 | lane_reg = PSB_LANE0; |
342 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); | 381 | cdv_sb_read(dev, lane_reg, &lane_value); |
343 | cdv_sb_write(dev, lane_reg, lane_value); | 382 | lane_value &= ~(LANE_PLL_MASK); |
344 | 383 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); | |
345 | lane_reg = PSB_LANE1; | 384 | cdv_sb_write(dev, lane_reg, lane_value); |
346 | cdv_sb_read(dev, lane_reg, &lane_value); | 385 | |
347 | lane_value &= ~(LANE_PLL_MASK); | 386 | lane_reg = PSB_LANE1; |
348 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); | 387 | cdv_sb_read(dev, lane_reg, &lane_value); |
349 | cdv_sb_write(dev, lane_reg, lane_value); | 388 | lane_value &= ~(LANE_PLL_MASK); |
350 | 389 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); | |
351 | lane_reg = PSB_LANE2; | 390 | cdv_sb_write(dev, lane_reg, lane_value); |
352 | cdv_sb_read(dev, lane_reg, &lane_value); | 391 | } else { |
353 | lane_value &= ~(LANE_PLL_MASK); | 392 | lane_reg = PSB_LANE2; |
354 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); | 393 | cdv_sb_read(dev, lane_reg, &lane_value); |
355 | cdv_sb_write(dev, lane_reg, lane_value); | 394 | lane_value &= ~(LANE_PLL_MASK); |
356 | 395 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); | |
357 | lane_reg = PSB_LANE3; | 396 | cdv_sb_write(dev, lane_reg, lane_value); |
358 | cdv_sb_read(dev, lane_reg, &lane_value); | 397 | |
359 | lane_value &= ~(LANE_PLL_MASK); | 398 | lane_reg = PSB_LANE3; |
360 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); | 399 | cdv_sb_read(dev, lane_reg, &lane_value); |
361 | cdv_sb_write(dev, lane_reg, lane_value); | 400 | lane_value &= ~(LANE_PLL_MASK); |
362 | 401 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); | |
402 | cdv_sb_write(dev, lane_reg, lane_value); | ||
403 | } | ||
404 | } | ||
363 | return 0; | 405 | return 0; |
364 | } | 406 | } |
365 | 407 | ||
@@ -396,6 +438,12 @@ static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc, | |||
396 | limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96]; | 438 | limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96]; |
397 | else | 439 | else |
398 | 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) || | ||
442 | psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { | ||
443 | if (refclk == 27000) | ||
444 | limit = &cdv_intel_limits[CDV_LIMIT_DP_27]; | ||
445 | else | ||
446 | limit = &cdv_intel_limits[CDV_LIMIT_DP_100]; | ||
399 | } else { | 447 | } else { |
400 | if (refclk == 27000) | 448 | if (refclk == 27000) |
401 | limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27]; | 449 | limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27]; |
@@ -438,13 +486,12 @@ static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc, | |||
438 | return true; | 486 | return true; |
439 | } | 487 | } |
440 | 488 | ||
441 | static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target, | 489 | static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit, |
442 | int refclk, | 490 | struct drm_crtc *crtc, int target, int refclk, |
443 | struct cdv_intel_clock_t *best_clock) | 491 | struct cdv_intel_clock_t *best_clock) |
444 | { | 492 | { |
445 | struct drm_device *dev = crtc->dev; | 493 | struct drm_device *dev = crtc->dev; |
446 | struct cdv_intel_clock_t clock; | 494 | struct cdv_intel_clock_t clock; |
447 | const struct cdv_intel_limit_t *limit = cdv_intel_limit(crtc, refclk); | ||
448 | int err = target; | 495 | int err = target; |
449 | 496 | ||
450 | 497 | ||
@@ -498,6 +545,49 @@ static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target, | |||
498 | return err != target; | 545 | return err != target; |
499 | } | 546 | } |
500 | 547 | ||
548 | static bool cdv_intel_find_dp_pll(const struct cdv_intel_limit_t *limit, struct drm_crtc *crtc, int target, | ||
549 | int refclk, | ||
550 | struct cdv_intel_clock_t *best_clock) | ||
551 | { | ||
552 | struct cdv_intel_clock_t clock; | ||
553 | if (refclk == 27000) { | ||
554 | if (target < 200000) { | ||
555 | clock.p1 = 2; | ||
556 | clock.p2 = 10; | ||
557 | clock.n = 1; | ||
558 | clock.m1 = 0; | ||
559 | clock.m2 = 118; | ||
560 | } else { | ||
561 | clock.p1 = 1; | ||
562 | clock.p2 = 10; | ||
563 | clock.n = 1; | ||
564 | clock.m1 = 0; | ||
565 | clock.m2 = 98; | ||
566 | } | ||
567 | } else if (refclk == 100000) { | ||
568 | if (target < 200000) { | ||
569 | clock.p1 = 2; | ||
570 | clock.p2 = 10; | ||
571 | clock.n = 5; | ||
572 | clock.m1 = 0; | ||
573 | clock.m2 = 160; | ||
574 | } else { | ||
575 | clock.p1 = 1; | ||
576 | clock.p2 = 10; | ||
577 | clock.n = 5; | ||
578 | clock.m1 = 0; | ||
579 | clock.m2 = 133; | ||
580 | } | ||
581 | } else | ||
582 | return false; | ||
583 | clock.m = clock.m2 + 2; | ||
584 | clock.p = clock.p1 * clock.p2; | ||
585 | clock.vco = (refclk * clock.m) / clock.n; | ||
586 | clock.dot = clock.vco / clock.p; | ||
587 | memcpy(best_clock, &clock, sizeof(struct cdv_intel_clock_t)); | ||
588 | return true; | ||
589 | } | ||
590 | |||
501 | static int cdv_intel_pipe_set_base(struct drm_crtc *crtc, | 591 | static int cdv_intel_pipe_set_base(struct drm_crtc *crtc, |
502 | int x, int y, struct drm_framebuffer *old_fb) | 592 | int x, int y, struct drm_framebuffer *old_fb) |
503 | { | 593 | { |
@@ -791,7 +881,7 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
791 | case DRM_MODE_DPMS_STANDBY: | 881 | case DRM_MODE_DPMS_STANDBY: |
792 | case DRM_MODE_DPMS_SUSPEND: | 882 | case DRM_MODE_DPMS_SUSPEND: |
793 | if (psb_intel_crtc->active) | 883 | if (psb_intel_crtc->active) |
794 | return; | 884 | break; |
795 | 885 | ||
796 | psb_intel_crtc->active = true; | 886 | psb_intel_crtc->active = true; |
797 | 887 | ||
@@ -835,17 +925,15 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
835 | REG_WRITE(map->status, temp); | 925 | REG_WRITE(map->status, temp); |
836 | REG_READ(map->status); | 926 | REG_READ(map->status); |
837 | 927 | ||
838 | cdv_intel_update_watermark(dev, crtc); | ||
839 | cdv_intel_crtc_load_lut(crtc); | 928 | cdv_intel_crtc_load_lut(crtc); |
840 | 929 | ||
841 | /* Give the overlay scaler a chance to enable | 930 | /* Give the overlay scaler a chance to enable |
842 | * if it's on this pipe */ | 931 | * if it's on this pipe */ |
843 | /* psb_intel_crtc_dpms_video(crtc, true); TODO */ | 932 | /* psb_intel_crtc_dpms_video(crtc, true); TODO */ |
844 | psb_intel_crtc->crtc_enable = true; | ||
845 | break; | 933 | break; |
846 | case DRM_MODE_DPMS_OFF: | 934 | case DRM_MODE_DPMS_OFF: |
847 | if (!psb_intel_crtc->active) | 935 | if (!psb_intel_crtc->active) |
848 | return; | 936 | break; |
849 | 937 | ||
850 | psb_intel_crtc->active = false; | 938 | psb_intel_crtc->active = false; |
851 | 939 | ||
@@ -892,10 +980,9 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
892 | 980 | ||
893 | /* Wait for the clocks to turn off. */ | 981 | /* Wait for the clocks to turn off. */ |
894 | udelay(150); | 982 | udelay(150); |
895 | cdv_intel_update_watermark(dev, crtc); | ||
896 | psb_intel_crtc->crtc_enable = false; | ||
897 | break; | 983 | break; |
898 | } | 984 | } |
985 | cdv_intel_update_watermark(dev, crtc); | ||
899 | /*Set FIFO Watermarks*/ | 986 | /*Set FIFO Watermarks*/ |
900 | REG_WRITE(DSPARB, 0x3F3E); | 987 | REG_WRITE(DSPARB, 0x3F3E); |
901 | } | 988 | } |
@@ -952,9 +1039,12 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
952 | u32 dpll = 0, dspcntr, pipeconf; | 1039 | u32 dpll = 0, dspcntr, pipeconf; |
953 | bool ok; | 1040 | bool ok; |
954 | bool is_crt = false, is_lvds = false, is_tv = false; | 1041 | bool is_crt = false, is_lvds = false, is_tv = false; |
955 | bool is_hdmi = false; | 1042 | bool is_hdmi = false, is_dp = false; |
956 | struct drm_mode_config *mode_config = &dev->mode_config; | 1043 | struct drm_mode_config *mode_config = &dev->mode_config; |
957 | struct drm_connector *connector; | 1044 | struct drm_connector *connector; |
1045 | const struct cdv_intel_limit_t *limit; | ||
1046 | u32 ddi_select = 0; | ||
1047 | bool is_edp = false; | ||
958 | 1048 | ||
959 | list_for_each_entry(connector, &mode_config->connector_list, head) { | 1049 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
960 | struct psb_intel_encoder *psb_intel_encoder = | 1050 | struct psb_intel_encoder *psb_intel_encoder = |
@@ -964,6 +1054,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
964 | || connector->encoder->crtc != crtc) | 1054 | || connector->encoder->crtc != crtc) |
965 | continue; | 1055 | continue; |
966 | 1056 | ||
1057 | ddi_select = psb_intel_encoder->ddi_select; | ||
967 | switch (psb_intel_encoder->type) { | 1058 | switch (psb_intel_encoder->type) { |
968 | case INTEL_OUTPUT_LVDS: | 1059 | case INTEL_OUTPUT_LVDS: |
969 | is_lvds = true; | 1060 | is_lvds = true; |
@@ -977,6 +1068,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
977 | case INTEL_OUTPUT_HDMI: | 1068 | case INTEL_OUTPUT_HDMI: |
978 | is_hdmi = true; | 1069 | is_hdmi = true; |
979 | break; | 1070 | break; |
1071 | case INTEL_OUTPUT_DISPLAYPORT: | ||
1072 | is_dp = true; | ||
1073 | break; | ||
1074 | case INTEL_OUTPUT_EDP: | ||
1075 | is_edp = true; | ||
1076 | break; | ||
1077 | default: | ||
1078 | DRM_ERROR("invalid output type.\n"); | ||
1079 | return 0; | ||
980 | } | 1080 | } |
981 | } | 1081 | } |
982 | 1082 | ||
@@ -986,6 +1086,20 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
986 | else | 1086 | else |
987 | /* high-end sku, 27/100 mhz */ | 1087 | /* high-end sku, 27/100 mhz */ |
988 | refclk = 27000; | 1088 | refclk = 27000; |
1089 | if (is_dp || is_edp) { | ||
1090 | /* | ||
1091 | * Based on the spec the low-end SKU has only CRT/LVDS. So it is | ||
1092 | * unnecessary to consider it for DP/eDP. | ||
1093 | * On the high-end SKU, it will use the 27/100M reference clk | ||
1094 | * for DP/eDP. When using SSC clock, the ref clk is 100MHz.Otherwise | ||
1095 | * it will be 27MHz. From the VBIOS code it seems that the pipe A choose | ||
1096 | * 27MHz for DP/eDP while the Pipe B chooses the 100MHz. | ||
1097 | */ | ||
1098 | if (pipe == 0) | ||
1099 | refclk = 27000; | ||
1100 | else | ||
1101 | refclk = 100000; | ||
1102 | } | ||
989 | 1103 | ||
990 | if (is_lvds && dev_priv->lvds_use_ssc) { | 1104 | if (is_lvds && dev_priv->lvds_use_ssc) { |
991 | refclk = dev_priv->lvds_ssc_freq * 1000; | 1105 | refclk = dev_priv->lvds_ssc_freq * 1000; |
@@ -993,8 +1107,10 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
993 | } | 1107 | } |
994 | 1108 | ||
995 | drm_mode_debug_printmodeline(adjusted_mode); | 1109 | drm_mode_debug_printmodeline(adjusted_mode); |
1110 | |||
1111 | limit = cdv_intel_limit(crtc, refclk); | ||
996 | 1112 | ||
997 | ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, | 1113 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, |
998 | &clock); | 1114 | &clock); |
999 | if (!ok) { | 1115 | if (!ok) { |
1000 | dev_err(dev->dev, "Couldn't find PLL settings for mode!\n"); | 1116 | dev_err(dev->dev, "Couldn't find PLL settings for mode!\n"); |
@@ -1009,6 +1125,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1009 | } | 1125 | } |
1010 | /* dpll |= PLL_REF_INPUT_DREFCLK; */ | 1126 | /* dpll |= PLL_REF_INPUT_DREFCLK; */ |
1011 | 1127 | ||
1128 | if (is_dp || is_edp) { | ||
1129 | cdv_intel_dp_set_m_n(crtc, mode, adjusted_mode); | ||
1130 | } else { | ||
1131 | REG_WRITE(PIPE_GMCH_DATA_M(pipe), 0); | ||
1132 | REG_WRITE(PIPE_GMCH_DATA_N(pipe), 0); | ||
1133 | REG_WRITE(PIPE_DP_LINK_M(pipe), 0); | ||
1134 | REG_WRITE(PIPE_DP_LINK_N(pipe), 0); | ||
1135 | } | ||
1136 | |||
1012 | dpll |= DPLL_SYNCLOCK_ENABLE; | 1137 | dpll |= DPLL_SYNCLOCK_ENABLE; |
1013 | /* if (is_lvds) | 1138 | /* if (is_lvds) |
1014 | dpll |= DPLLB_MODE_LVDS; | 1139 | dpll |= DPLLB_MODE_LVDS; |
@@ -1019,6 +1144,31 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1019 | /* setup pipeconf */ | 1144 | /* setup pipeconf */ |
1020 | pipeconf = REG_READ(map->conf); | 1145 | pipeconf = REG_READ(map->conf); |
1021 | 1146 | ||
1147 | pipeconf &= ~(PIPE_BPC_MASK); | ||
1148 | if (is_edp) { | ||
1149 | switch (dev_priv->edp.bpp) { | ||
1150 | case 24: | ||
1151 | pipeconf |= PIPE_8BPC; | ||
1152 | break; | ||
1153 | case 18: | ||
1154 | pipeconf |= PIPE_6BPC; | ||
1155 | break; | ||
1156 | case 30: | ||
1157 | pipeconf |= PIPE_10BPC; | ||
1158 | break; | ||
1159 | default: | ||
1160 | pipeconf |= PIPE_8BPC; | ||
1161 | break; | ||
1162 | } | ||
1163 | } else if (is_lvds) { | ||
1164 | /* the BPC will be 6 if it is 18-bit LVDS panel */ | ||
1165 | if ((REG_READ(LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) | ||
1166 | pipeconf |= PIPE_8BPC; | ||
1167 | else | ||
1168 | pipeconf |= PIPE_6BPC; | ||
1169 | } else | ||
1170 | pipeconf |= PIPE_8BPC; | ||
1171 | |||
1022 | /* Set up the display plane register */ | 1172 | /* Set up the display plane register */ |
1023 | dspcntr = DISPPLANE_GAMMA_ENABLE; | 1173 | dspcntr = DISPPLANE_GAMMA_ENABLE; |
1024 | 1174 | ||
@@ -1033,7 +1183,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1033 | REG_WRITE(map->dpll, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); | 1183 | REG_WRITE(map->dpll, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); |
1034 | REG_READ(map->dpll); | 1184 | REG_READ(map->dpll); |
1035 | 1185 | ||
1036 | cdv_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds); | 1186 | cdv_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds, ddi_select); |
1037 | 1187 | ||
1038 | udelay(150); | 1188 | udelay(150); |
1039 | 1189 | ||
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c new file mode 100644 index 000000000000..e3a3978cf320 --- /dev/null +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c | |||
@@ -0,0 +1,1950 @@ | |||
1 | /* | ||
2 | * Copyright © 2012 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 <keithp@keithp.com> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <drm/drmP.h> | ||
31 | #include <drm/drm_crtc.h> | ||
32 | #include <drm/drm_crtc_helper.h> | ||
33 | #include "psb_drv.h" | ||
34 | #include "psb_intel_drv.h" | ||
35 | #include "psb_intel_reg.h" | ||
36 | #include <drm/drm_dp_helper.h> | ||
37 | |||
38 | #define _wait_for(COND, MS, W) ({ \ | ||
39 | unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ | ||
40 | int ret__ = 0; \ | ||
41 | while (! (COND)) { \ | ||
42 | if (time_after(jiffies, timeout__)) { \ | ||
43 | ret__ = -ETIMEDOUT; \ | ||
44 | break; \ | ||
45 | } \ | ||
46 | if (W && !in_dbg_master()) msleep(W); \ | ||
47 | } \ | ||
48 | ret__; \ | ||
49 | }) | ||
50 | |||
51 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) | ||
52 | |||
53 | #define DP_LINK_STATUS_SIZE 6 | ||
54 | #define DP_LINK_CHECK_TIMEOUT (10 * 1000) | ||
55 | |||
56 | #define DP_LINK_CONFIGURATION_SIZE 9 | ||
57 | |||
58 | #define CDV_FAST_LINK_TRAIN 1 | ||
59 | |||
60 | struct cdv_intel_dp { | ||
61 | uint32_t output_reg; | ||
62 | uint32_t DP; | ||
63 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; | ||
64 | bool has_audio; | ||
65 | int force_audio; | ||
66 | uint32_t color_range; | ||
67 | uint8_t link_bw; | ||
68 | uint8_t lane_count; | ||
69 | uint8_t dpcd[4]; | ||
70 | struct psb_intel_encoder *encoder; | ||
71 | struct i2c_adapter adapter; | ||
72 | struct i2c_algo_dp_aux_data algo; | ||
73 | uint8_t train_set[4]; | ||
74 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
75 | int panel_power_up_delay; | ||
76 | int panel_power_down_delay; | ||
77 | int panel_power_cycle_delay; | ||
78 | int backlight_on_delay; | ||
79 | int backlight_off_delay; | ||
80 | struct drm_display_mode *panel_fixed_mode; /* for eDP */ | ||
81 | bool panel_on; | ||
82 | }; | ||
83 | |||
84 | struct ddi_regoff { | ||
85 | uint32_t PreEmph1; | ||
86 | uint32_t PreEmph2; | ||
87 | uint32_t VSwing1; | ||
88 | uint32_t VSwing2; | ||
89 | uint32_t VSwing3; | ||
90 | uint32_t VSwing4; | ||
91 | uint32_t VSwing5; | ||
92 | }; | ||
93 | |||
94 | static struct ddi_regoff ddi_DP_train_table[] = { | ||
95 | {.PreEmph1 = 0x812c, .PreEmph2 = 0x8124, .VSwing1 = 0x8154, | ||
96 | .VSwing2 = 0x8148, .VSwing3 = 0x814C, .VSwing4 = 0x8150, | ||
97 | .VSwing5 = 0x8158,}, | ||
98 | {.PreEmph1 = 0x822c, .PreEmph2 = 0x8224, .VSwing1 = 0x8254, | ||
99 | .VSwing2 = 0x8248, .VSwing3 = 0x824C, .VSwing4 = 0x8250, | ||
100 | .VSwing5 = 0x8258,}, | ||
101 | }; | ||
102 | |||
103 | static uint32_t dp_vswing_premph_table[] = { | ||
104 | 0x55338954, 0x4000, | ||
105 | 0x554d8954, 0x2000, | ||
106 | 0x55668954, 0, | ||
107 | 0x559ac0d4, 0x6000, | ||
108 | }; | ||
109 | /** | ||
110 | * is_edp - is the given port attached to an eDP panel (either CPU or PCH) | ||
111 | * @intel_dp: DP struct | ||
112 | * | ||
113 | * If a CPU or PCH DP output is attached to an eDP panel, this function | ||
114 | * will return true, and false otherwise. | ||
115 | */ | ||
116 | static bool is_edp(struct psb_intel_encoder *encoder) | ||
117 | { | ||
118 | return encoder->type == INTEL_OUTPUT_EDP; | ||
119 | } | ||
120 | |||
121 | |||
122 | static void cdv_intel_dp_start_link_train(struct psb_intel_encoder *encoder); | ||
123 | static void cdv_intel_dp_complete_link_train(struct psb_intel_encoder *encoder); | ||
124 | static void cdv_intel_dp_link_down(struct psb_intel_encoder *encoder); | ||
125 | |||
126 | static int | ||
127 | cdv_intel_dp_max_lane_count(struct psb_intel_encoder *encoder) | ||
128 | { | ||
129 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
130 | int max_lane_count = 4; | ||
131 | |||
132 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) { | ||
133 | max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; | ||
134 | switch (max_lane_count) { | ||
135 | case 1: case 2: case 4: | ||
136 | break; | ||
137 | default: | ||
138 | max_lane_count = 4; | ||
139 | } | ||
140 | } | ||
141 | return max_lane_count; | ||
142 | } | ||
143 | |||
144 | static int | ||
145 | cdv_intel_dp_max_link_bw(struct psb_intel_encoder *encoder) | ||
146 | { | ||
147 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
148 | int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE]; | ||
149 | |||
150 | switch (max_link_bw) { | ||
151 | case DP_LINK_BW_1_62: | ||
152 | case DP_LINK_BW_2_7: | ||
153 | break; | ||
154 | default: | ||
155 | max_link_bw = DP_LINK_BW_1_62; | ||
156 | break; | ||
157 | } | ||
158 | return max_link_bw; | ||
159 | } | ||
160 | |||
161 | static int | ||
162 | cdv_intel_dp_link_clock(uint8_t link_bw) | ||
163 | { | ||
164 | if (link_bw == DP_LINK_BW_2_7) | ||
165 | return 270000; | ||
166 | else | ||
167 | return 162000; | ||
168 | } | ||
169 | |||
170 | static int | ||
171 | cdv_intel_dp_link_required(int pixel_clock, int bpp) | ||
172 | { | ||
173 | return (pixel_clock * bpp + 7) / 8; | ||
174 | } | ||
175 | |||
176 | static int | ||
177 | cdv_intel_dp_max_data_rate(int max_link_clock, int max_lanes) | ||
178 | { | ||
179 | return (max_link_clock * max_lanes * 19) / 20; | ||
180 | } | ||
181 | |||
182 | static void cdv_intel_edp_panel_vdd_on(struct psb_intel_encoder *intel_encoder) | ||
183 | { | ||
184 | struct drm_device *dev = intel_encoder->base.dev; | ||
185 | struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; | ||
186 | u32 pp; | ||
187 | |||
188 | if (intel_dp->panel_on) { | ||
189 | DRM_DEBUG_KMS("Skip VDD on because of panel on\n"); | ||
190 | return; | ||
191 | } | ||
192 | DRM_DEBUG_KMS("\n"); | ||
193 | |||
194 | pp = REG_READ(PP_CONTROL); | ||
195 | |||
196 | pp |= EDP_FORCE_VDD; | ||
197 | REG_WRITE(PP_CONTROL, pp); | ||
198 | REG_READ(PP_CONTROL); | ||
199 | msleep(intel_dp->panel_power_up_delay); | ||
200 | } | ||
201 | |||
202 | static void cdv_intel_edp_panel_vdd_off(struct psb_intel_encoder *intel_encoder) | ||
203 | { | ||
204 | struct drm_device *dev = intel_encoder->base.dev; | ||
205 | u32 pp; | ||
206 | |||
207 | DRM_DEBUG_KMS("\n"); | ||
208 | pp = REG_READ(PP_CONTROL); | ||
209 | |||
210 | pp &= ~EDP_FORCE_VDD; | ||
211 | REG_WRITE(PP_CONTROL, pp); | ||
212 | REG_READ(PP_CONTROL); | ||
213 | |||
214 | } | ||
215 | |||
216 | /* Returns true if the panel was already on when called */ | ||
217 | static bool cdv_intel_edp_panel_on(struct psb_intel_encoder *intel_encoder) | ||
218 | { | ||
219 | struct drm_device *dev = intel_encoder->base.dev; | ||
220 | struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; | ||
221 | u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_NONE; | ||
222 | |||
223 | if (intel_dp->panel_on) | ||
224 | return true; | ||
225 | |||
226 | DRM_DEBUG_KMS("\n"); | ||
227 | pp = REG_READ(PP_CONTROL); | ||
228 | pp &= ~PANEL_UNLOCK_MASK; | ||
229 | |||
230 | pp |= (PANEL_UNLOCK_REGS | POWER_TARGET_ON); | ||
231 | REG_WRITE(PP_CONTROL, pp); | ||
232 | REG_READ(PP_CONTROL); | ||
233 | |||
234 | if (wait_for(((REG_READ(PP_STATUS) & idle_on_mask) == idle_on_mask), 1000)) { | ||
235 | DRM_DEBUG_KMS("Error in Powering up eDP panel, status %x\n", REG_READ(PP_STATUS)); | ||
236 | intel_dp->panel_on = false; | ||
237 | } else | ||
238 | intel_dp->panel_on = true; | ||
239 | msleep(intel_dp->panel_power_up_delay); | ||
240 | |||
241 | return false; | ||
242 | } | ||
243 | |||
244 | static void cdv_intel_edp_panel_off (struct psb_intel_encoder *intel_encoder) | ||
245 | { | ||
246 | struct drm_device *dev = intel_encoder->base.dev; | ||
247 | u32 pp, idle_off_mask = PP_ON ; | ||
248 | struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; | ||
249 | |||
250 | DRM_DEBUG_KMS("\n"); | ||
251 | |||
252 | pp = REG_READ(PP_CONTROL); | ||
253 | |||
254 | if ((pp & POWER_TARGET_ON) == 0) | ||
255 | return; | ||
256 | |||
257 | intel_dp->panel_on = false; | ||
258 | pp &= ~PANEL_UNLOCK_MASK; | ||
259 | /* ILK workaround: disable reset around power sequence */ | ||
260 | |||
261 | pp &= ~POWER_TARGET_ON; | ||
262 | pp &= ~EDP_FORCE_VDD; | ||
263 | pp &= ~EDP_BLC_ENABLE; | ||
264 | REG_WRITE(PP_CONTROL, pp); | ||
265 | REG_READ(PP_CONTROL); | ||
266 | DRM_DEBUG_KMS("PP_STATUS %x\n", REG_READ(PP_STATUS)); | ||
267 | |||
268 | if (wait_for((REG_READ(PP_STATUS) & idle_off_mask) == 0, 1000)) { | ||
269 | DRM_DEBUG_KMS("Error in turning off Panel\n"); | ||
270 | } | ||
271 | |||
272 | msleep(intel_dp->panel_power_cycle_delay); | ||
273 | DRM_DEBUG_KMS("Over\n"); | ||
274 | } | ||
275 | |||
276 | static void cdv_intel_edp_backlight_on (struct psb_intel_encoder *intel_encoder) | ||
277 | { | ||
278 | struct drm_device *dev = intel_encoder->base.dev; | ||
279 | u32 pp; | ||
280 | |||
281 | DRM_DEBUG_KMS("\n"); | ||
282 | /* | ||
283 | * If we enable the backlight right away following a panel power | ||
284 | * on, we may see slight flicker as the panel syncs with the eDP | ||
285 | * link. So delay a bit to make sure the image is solid before | ||
286 | * allowing it to appear. | ||
287 | */ | ||
288 | msleep(300); | ||
289 | pp = REG_READ(PP_CONTROL); | ||
290 | |||
291 | pp |= EDP_BLC_ENABLE; | ||
292 | REG_WRITE(PP_CONTROL, pp); | ||
293 | gma_backlight_enable(dev); | ||
294 | } | ||
295 | |||
296 | static void cdv_intel_edp_backlight_off (struct psb_intel_encoder *intel_encoder) | ||
297 | { | ||
298 | struct drm_device *dev = intel_encoder->base.dev; | ||
299 | struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; | ||
300 | u32 pp; | ||
301 | |||
302 | DRM_DEBUG_KMS("\n"); | ||
303 | gma_backlight_disable(dev); | ||
304 | msleep(10); | ||
305 | pp = REG_READ(PP_CONTROL); | ||
306 | |||
307 | pp &= ~EDP_BLC_ENABLE; | ||
308 | REG_WRITE(PP_CONTROL, pp); | ||
309 | msleep(intel_dp->backlight_off_delay); | ||
310 | } | ||
311 | |||
312 | static int | ||
313 | cdv_intel_dp_mode_valid(struct drm_connector *connector, | ||
314 | struct drm_display_mode *mode) | ||
315 | { | ||
316 | struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector); | ||
317 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
318 | int max_link_clock = cdv_intel_dp_link_clock(cdv_intel_dp_max_link_bw(encoder)); | ||
319 | int max_lanes = cdv_intel_dp_max_lane_count(encoder); | ||
320 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
321 | |||
322 | if (is_edp(encoder) && intel_dp->panel_fixed_mode) { | ||
323 | if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) | ||
324 | return MODE_PANEL; | ||
325 | if (mode->vdisplay > intel_dp->panel_fixed_mode->vdisplay) | ||
326 | return MODE_PANEL; | ||
327 | } | ||
328 | |||
329 | /* only refuse the mode on non eDP since we have seen some weird eDP panels | ||
330 | which are outside spec tolerances but somehow work by magic */ | ||
331 | if (!is_edp(encoder) && | ||
332 | (cdv_intel_dp_link_required(mode->clock, dev_priv->edp.bpp) | ||
333 | > cdv_intel_dp_max_data_rate(max_link_clock, max_lanes))) | ||
334 | return MODE_CLOCK_HIGH; | ||
335 | |||
336 | if (is_edp(encoder)) { | ||
337 | if (cdv_intel_dp_link_required(mode->clock, 24) | ||
338 | > cdv_intel_dp_max_data_rate(max_link_clock, max_lanes)) | ||
339 | return MODE_CLOCK_HIGH; | ||
340 | |||
341 | } | ||
342 | if (mode->clock < 10000) | ||
343 | return MODE_CLOCK_LOW; | ||
344 | |||
345 | return MODE_OK; | ||
346 | } | ||
347 | |||
348 | static uint32_t | ||
349 | pack_aux(uint8_t *src, int src_bytes) | ||
350 | { | ||
351 | int i; | ||
352 | uint32_t v = 0; | ||
353 | |||
354 | if (src_bytes > 4) | ||
355 | src_bytes = 4; | ||
356 | for (i = 0; i < src_bytes; i++) | ||
357 | v |= ((uint32_t) src[i]) << ((3-i) * 8); | ||
358 | return v; | ||
359 | } | ||
360 | |||
361 | static void | ||
362 | unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) | ||
363 | { | ||
364 | int i; | ||
365 | if (dst_bytes > 4) | ||
366 | dst_bytes = 4; | ||
367 | for (i = 0; i < dst_bytes; i++) | ||
368 | dst[i] = src >> ((3-i) * 8); | ||
369 | } | ||
370 | |||
371 | static int | ||
372 | cdv_intel_dp_aux_ch(struct psb_intel_encoder *encoder, | ||
373 | uint8_t *send, int send_bytes, | ||
374 | uint8_t *recv, int recv_size) | ||
375 | { | ||
376 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
377 | uint32_t output_reg = intel_dp->output_reg; | ||
378 | struct drm_device *dev = encoder->base.dev; | ||
379 | uint32_t ch_ctl = output_reg + 0x10; | ||
380 | uint32_t ch_data = ch_ctl + 4; | ||
381 | int i; | ||
382 | int recv_bytes; | ||
383 | uint32_t status; | ||
384 | uint32_t aux_clock_divider; | ||
385 | int try, precharge; | ||
386 | |||
387 | /* The clock divider is based off the hrawclk, | ||
388 | * and would like to run at 2MHz. So, take the | ||
389 | * hrawclk value and divide by 2 and use that | ||
390 | * On CDV platform it uses 200MHz as hrawclk. | ||
391 | * | ||
392 | */ | ||
393 | aux_clock_divider = 200 / 2; | ||
394 | |||
395 | precharge = 4; | ||
396 | if (is_edp(encoder)) | ||
397 | precharge = 10; | ||
398 | |||
399 | if (REG_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) { | ||
400 | DRM_ERROR("dp_aux_ch not started status 0x%08x\n", | ||
401 | REG_READ(ch_ctl)); | ||
402 | return -EBUSY; | ||
403 | } | ||
404 | |||
405 | /* Must try at least 3 times according to DP spec */ | ||
406 | for (try = 0; try < 5; try++) { | ||
407 | /* Load the send data into the aux channel data registers */ | ||
408 | for (i = 0; i < send_bytes; i += 4) | ||
409 | REG_WRITE(ch_data + i, | ||
410 | pack_aux(send + i, send_bytes - i)); | ||
411 | |||
412 | /* Send the command and wait for it to complete */ | ||
413 | REG_WRITE(ch_ctl, | ||
414 | DP_AUX_CH_CTL_SEND_BUSY | | ||
415 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
416 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
417 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
418 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | ||
419 | DP_AUX_CH_CTL_DONE | | ||
420 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
421 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
422 | for (;;) { | ||
423 | status = REG_READ(ch_ctl); | ||
424 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) | ||
425 | break; | ||
426 | udelay(100); | ||
427 | } | ||
428 | |||
429 | /* Clear done status and any errors */ | ||
430 | REG_WRITE(ch_ctl, | ||
431 | status | | ||
432 | DP_AUX_CH_CTL_DONE | | ||
433 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
434 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
435 | if (status & DP_AUX_CH_CTL_DONE) | ||
436 | break; | ||
437 | } | ||
438 | |||
439 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { | ||
440 | DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status); | ||
441 | return -EBUSY; | ||
442 | } | ||
443 | |||
444 | /* Check for timeout or receive error. | ||
445 | * Timeouts occur when the sink is not connected | ||
446 | */ | ||
447 | if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { | ||
448 | DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status); | ||
449 | return -EIO; | ||
450 | } | ||
451 | |||
452 | /* Timeouts occur when the device isn't connected, so they're | ||
453 | * "normal" -- don't fill the kernel log with these */ | ||
454 | if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { | ||
455 | DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status); | ||
456 | return -ETIMEDOUT; | ||
457 | } | ||
458 | |||
459 | /* Unload any bytes sent back from the other side */ | ||
460 | recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> | ||
461 | DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); | ||
462 | if (recv_bytes > recv_size) | ||
463 | recv_bytes = recv_size; | ||
464 | |||
465 | for (i = 0; i < recv_bytes; i += 4) | ||
466 | unpack_aux(REG_READ(ch_data + i), | ||
467 | recv + i, recv_bytes - i); | ||
468 | |||
469 | return recv_bytes; | ||
470 | } | ||
471 | |||
472 | /* Write data to the aux channel in native mode */ | ||
473 | static int | ||
474 | cdv_intel_dp_aux_native_write(struct psb_intel_encoder *encoder, | ||
475 | uint16_t address, uint8_t *send, int send_bytes) | ||
476 | { | ||
477 | int ret; | ||
478 | uint8_t msg[20]; | ||
479 | int msg_bytes; | ||
480 | uint8_t ack; | ||
481 | |||
482 | if (send_bytes > 16) | ||
483 | return -1; | ||
484 | msg[0] = AUX_NATIVE_WRITE << 4; | ||
485 | msg[1] = address >> 8; | ||
486 | msg[2] = address & 0xff; | ||
487 | msg[3] = send_bytes - 1; | ||
488 | memcpy(&msg[4], send, send_bytes); | ||
489 | msg_bytes = send_bytes + 4; | ||
490 | for (;;) { | ||
491 | ret = cdv_intel_dp_aux_ch(encoder, msg, msg_bytes, &ack, 1); | ||
492 | if (ret < 0) | ||
493 | return ret; | ||
494 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) | ||
495 | break; | ||
496 | else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) | ||
497 | udelay(100); | ||
498 | else | ||
499 | return -EIO; | ||
500 | } | ||
501 | return send_bytes; | ||
502 | } | ||
503 | |||
504 | /* Write a single byte to the aux channel in native mode */ | ||
505 | static int | ||
506 | cdv_intel_dp_aux_native_write_1(struct psb_intel_encoder *encoder, | ||
507 | uint16_t address, uint8_t byte) | ||
508 | { | ||
509 | return cdv_intel_dp_aux_native_write(encoder, address, &byte, 1); | ||
510 | } | ||
511 | |||
512 | /* read bytes from a native aux channel */ | ||
513 | static int | ||
514 | cdv_intel_dp_aux_native_read(struct psb_intel_encoder *encoder, | ||
515 | uint16_t address, uint8_t *recv, int recv_bytes) | ||
516 | { | ||
517 | uint8_t msg[4]; | ||
518 | int msg_bytes; | ||
519 | uint8_t reply[20]; | ||
520 | int reply_bytes; | ||
521 | uint8_t ack; | ||
522 | int ret; | ||
523 | |||
524 | msg[0] = AUX_NATIVE_READ << 4; | ||
525 | msg[1] = address >> 8; | ||
526 | msg[2] = address & 0xff; | ||
527 | msg[3] = recv_bytes - 1; | ||
528 | |||
529 | msg_bytes = 4; | ||
530 | reply_bytes = recv_bytes + 1; | ||
531 | |||
532 | for (;;) { | ||
533 | ret = cdv_intel_dp_aux_ch(encoder, msg, msg_bytes, | ||
534 | reply, reply_bytes); | ||
535 | if (ret == 0) | ||
536 | return -EPROTO; | ||
537 | if (ret < 0) | ||
538 | return ret; | ||
539 | ack = reply[0]; | ||
540 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) { | ||
541 | memcpy(recv, reply + 1, ret - 1); | ||
542 | return ret - 1; | ||
543 | } | ||
544 | else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) | ||
545 | udelay(100); | ||
546 | else | ||
547 | return -EIO; | ||
548 | } | ||
549 | } | ||
550 | |||
551 | static int | ||
552 | cdv_intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | ||
553 | uint8_t write_byte, uint8_t *read_byte) | ||
554 | { | ||
555 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
556 | struct cdv_intel_dp *intel_dp = container_of(adapter, | ||
557 | struct cdv_intel_dp, | ||
558 | adapter); | ||
559 | struct psb_intel_encoder *encoder = intel_dp->encoder; | ||
560 | uint16_t address = algo_data->address; | ||
561 | uint8_t msg[5]; | ||
562 | uint8_t reply[2]; | ||
563 | unsigned retry; | ||
564 | int msg_bytes; | ||
565 | int reply_bytes; | ||
566 | int ret; | ||
567 | |||
568 | /* Set up the command byte */ | ||
569 | if (mode & MODE_I2C_READ) | ||
570 | msg[0] = AUX_I2C_READ << 4; | ||
571 | else | ||
572 | msg[0] = AUX_I2C_WRITE << 4; | ||
573 | |||
574 | if (!(mode & MODE_I2C_STOP)) | ||
575 | msg[0] |= AUX_I2C_MOT << 4; | ||
576 | |||
577 | msg[1] = address >> 8; | ||
578 | msg[2] = address; | ||
579 | |||
580 | switch (mode) { | ||
581 | case MODE_I2C_WRITE: | ||
582 | msg[3] = 0; | ||
583 | msg[4] = write_byte; | ||
584 | msg_bytes = 5; | ||
585 | reply_bytes = 1; | ||
586 | break; | ||
587 | case MODE_I2C_READ: | ||
588 | msg[3] = 0; | ||
589 | msg_bytes = 4; | ||
590 | reply_bytes = 2; | ||
591 | break; | ||
592 | default: | ||
593 | msg_bytes = 3; | ||
594 | reply_bytes = 1; | ||
595 | break; | ||
596 | } | ||
597 | |||
598 | for (retry = 0; retry < 5; retry++) { | ||
599 | ret = cdv_intel_dp_aux_ch(encoder, | ||
600 | msg, msg_bytes, | ||
601 | reply, reply_bytes); | ||
602 | if (ret < 0) { | ||
603 | DRM_DEBUG_KMS("aux_ch failed %d\n", ret); | ||
604 | return ret; | ||
605 | } | ||
606 | |||
607 | switch (reply[0] & AUX_NATIVE_REPLY_MASK) { | ||
608 | case AUX_NATIVE_REPLY_ACK: | ||
609 | /* I2C-over-AUX Reply field is only valid | ||
610 | * when paired with AUX ACK. | ||
611 | */ | ||
612 | break; | ||
613 | case AUX_NATIVE_REPLY_NACK: | ||
614 | DRM_DEBUG_KMS("aux_ch native nack\n"); | ||
615 | return -EREMOTEIO; | ||
616 | case AUX_NATIVE_REPLY_DEFER: | ||
617 | udelay(100); | ||
618 | continue; | ||
619 | default: | ||
620 | DRM_ERROR("aux_ch invalid native reply 0x%02x\n", | ||
621 | reply[0]); | ||
622 | return -EREMOTEIO; | ||
623 | } | ||
624 | |||
625 | switch (reply[0] & AUX_I2C_REPLY_MASK) { | ||
626 | case AUX_I2C_REPLY_ACK: | ||
627 | if (mode == MODE_I2C_READ) { | ||
628 | *read_byte = reply[1]; | ||
629 | } | ||
630 | return reply_bytes - 1; | ||
631 | case AUX_I2C_REPLY_NACK: | ||
632 | DRM_DEBUG_KMS("aux_i2c nack\n"); | ||
633 | return -EREMOTEIO; | ||
634 | case AUX_I2C_REPLY_DEFER: | ||
635 | DRM_DEBUG_KMS("aux_i2c defer\n"); | ||
636 | udelay(100); | ||
637 | break; | ||
638 | default: | ||
639 | DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]); | ||
640 | return -EREMOTEIO; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | DRM_ERROR("too many retries, giving up\n"); | ||
645 | return -EREMOTEIO; | ||
646 | } | ||
647 | |||
648 | static int | ||
649 | cdv_intel_dp_i2c_init(struct psb_intel_connector *connector, struct psb_intel_encoder *encoder, const char *name) | ||
650 | { | ||
651 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
652 | int ret; | ||
653 | |||
654 | DRM_DEBUG_KMS("i2c_init %s\n", name); | ||
655 | |||
656 | intel_dp->algo.running = false; | ||
657 | intel_dp->algo.address = 0; | ||
658 | intel_dp->algo.aux_ch = cdv_intel_dp_i2c_aux_ch; | ||
659 | |||
660 | memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter)); | ||
661 | intel_dp->adapter.owner = THIS_MODULE; | ||
662 | intel_dp->adapter.class = I2C_CLASS_DDC; | ||
663 | strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1); | ||
664 | intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0'; | ||
665 | intel_dp->adapter.algo_data = &intel_dp->algo; | ||
666 | intel_dp->adapter.dev.parent = &connector->base.kdev; | ||
667 | |||
668 | if (is_edp(encoder)) | ||
669 | cdv_intel_edp_panel_vdd_on(encoder); | ||
670 | ret = i2c_dp_aux_add_bus(&intel_dp->adapter); | ||
671 | if (is_edp(encoder)) | ||
672 | cdv_intel_edp_panel_vdd_off(encoder); | ||
673 | |||
674 | return ret; | ||
675 | } | ||
676 | |||
677 | void cdv_intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | ||
678 | struct drm_display_mode *adjusted_mode) | ||
679 | { | ||
680 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | ||
681 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
682 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
683 | adjusted_mode->htotal = fixed_mode->htotal; | ||
684 | |||
685 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
686 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
687 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
688 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
689 | |||
690 | adjusted_mode->clock = fixed_mode->clock; | ||
691 | |||
692 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
693 | } | ||
694 | |||
695 | static bool | ||
696 | cdv_intel_dp_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, | ||
697 | struct drm_display_mode *adjusted_mode) | ||
698 | { | ||
699 | struct drm_psb_private *dev_priv = encoder->dev->dev_private; | ||
700 | struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); | ||
701 | struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; | ||
702 | int lane_count, clock; | ||
703 | int max_lane_count = cdv_intel_dp_max_lane_count(intel_encoder); | ||
704 | int max_clock = cdv_intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; | ||
705 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | ||
706 | int refclock = mode->clock; | ||
707 | int bpp = 24; | ||
708 | |||
709 | if (is_edp(intel_encoder) && intel_dp->panel_fixed_mode) { | ||
710 | cdv_intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode); | ||
711 | refclock = intel_dp->panel_fixed_mode->clock; | ||
712 | bpp = dev_priv->edp.bpp; | ||
713 | } | ||
714 | |||
715 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | ||
716 | for (clock = max_clock; clock >= 0; clock--) { | ||
717 | int link_avail = cdv_intel_dp_max_data_rate(cdv_intel_dp_link_clock(bws[clock]), lane_count); | ||
718 | |||
719 | if (cdv_intel_dp_link_required(refclock, bpp) <= link_avail) { | ||
720 | intel_dp->link_bw = bws[clock]; | ||
721 | intel_dp->lane_count = lane_count; | ||
722 | adjusted_mode->clock = cdv_intel_dp_link_clock(intel_dp->link_bw); | ||
723 | DRM_DEBUG_KMS("Display port link bw %02x lane " | ||
724 | "count %d clock %d\n", | ||
725 | intel_dp->link_bw, intel_dp->lane_count, | ||
726 | adjusted_mode->clock); | ||
727 | return true; | ||
728 | } | ||
729 | } | ||
730 | } | ||
731 | if (is_edp(intel_encoder)) { | ||
732 | /* okay we failed just pick the highest */ | ||
733 | intel_dp->lane_count = max_lane_count; | ||
734 | intel_dp->link_bw = bws[max_clock]; | ||
735 | adjusted_mode->clock = cdv_intel_dp_link_clock(intel_dp->link_bw); | ||
736 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " | ||
737 | "count %d clock %d\n", | ||
738 | intel_dp->link_bw, intel_dp->lane_count, | ||
739 | adjusted_mode->clock); | ||
740 | |||
741 | return true; | ||
742 | } | ||
743 | return false; | ||
744 | } | ||
745 | |||
746 | struct cdv_intel_dp_m_n { | ||
747 | uint32_t tu; | ||
748 | uint32_t gmch_m; | ||
749 | uint32_t gmch_n; | ||
750 | uint32_t link_m; | ||
751 | uint32_t link_n; | ||
752 | }; | ||
753 | |||
754 | static void | ||
755 | cdv_intel_reduce_ratio(uint32_t *num, uint32_t *den) | ||
756 | { | ||
757 | /* | ||
758 | while (*num > 0xffffff || *den > 0xffffff) { | ||
759 | *num >>= 1; | ||
760 | *den >>= 1; | ||
761 | }*/ | ||
762 | uint64_t value, m; | ||
763 | m = *num; | ||
764 | value = m * (0x800000); | ||
765 | m = do_div(value, *den); | ||
766 | *num = value; | ||
767 | *den = 0x800000; | ||
768 | } | ||
769 | |||
770 | static void | ||
771 | cdv_intel_dp_compute_m_n(int bpp, | ||
772 | int nlanes, | ||
773 | int pixel_clock, | ||
774 | int link_clock, | ||
775 | struct cdv_intel_dp_m_n *m_n) | ||
776 | { | ||
777 | m_n->tu = 64; | ||
778 | m_n->gmch_m = (pixel_clock * bpp + 7) >> 3; | ||
779 | m_n->gmch_n = link_clock * nlanes; | ||
780 | cdv_intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | ||
781 | m_n->link_m = pixel_clock; | ||
782 | m_n->link_n = link_clock; | ||
783 | cdv_intel_reduce_ratio(&m_n->link_m, &m_n->link_n); | ||
784 | } | ||
785 | |||
786 | void | ||
787 | cdv_intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | ||
788 | struct drm_display_mode *adjusted_mode) | ||
789 | { | ||
790 | struct drm_device *dev = crtc->dev; | ||
791 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
792 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
793 | struct drm_encoder *encoder; | ||
794 | struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); | ||
795 | int lane_count = 4, bpp = 24; | ||
796 | struct cdv_intel_dp_m_n m_n; | ||
797 | int pipe = intel_crtc->pipe; | ||
798 | |||
799 | /* | ||
800 | * Find the lane count in the intel_encoder private | ||
801 | */ | ||
802 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | ||
803 | struct psb_intel_encoder *intel_encoder; | ||
804 | struct cdv_intel_dp *intel_dp; | ||
805 | |||
806 | if (encoder->crtc != crtc) | ||
807 | continue; | ||
808 | |||
809 | intel_encoder = to_psb_intel_encoder(encoder); | ||
810 | intel_dp = intel_encoder->dev_priv; | ||
811 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | ||
812 | lane_count = intel_dp->lane_count; | ||
813 | break; | ||
814 | } else if (is_edp(intel_encoder)) { | ||
815 | lane_count = intel_dp->lane_count; | ||
816 | bpp = dev_priv->edp.bpp; | ||
817 | break; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | /* | ||
822 | * Compute the GMCH and Link ratios. The '3' here is | ||
823 | * the number of bytes_per_pixel post-LUT, which we always | ||
824 | * set up for 8-bits of R/G/B, or 3 bytes total. | ||
825 | */ | ||
826 | cdv_intel_dp_compute_m_n(bpp, lane_count, | ||
827 | mode->clock, adjusted_mode->clock, &m_n); | ||
828 | |||
829 | { | ||
830 | REG_WRITE(PIPE_GMCH_DATA_M(pipe), | ||
831 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | ||
832 | m_n.gmch_m); | ||
833 | REG_WRITE(PIPE_GMCH_DATA_N(pipe), m_n.gmch_n); | ||
834 | REG_WRITE(PIPE_DP_LINK_M(pipe), m_n.link_m); | ||
835 | REG_WRITE(PIPE_DP_LINK_N(pipe), m_n.link_n); | ||
836 | } | ||
837 | } | ||
838 | |||
839 | static void | ||
840 | cdv_intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | ||
841 | struct drm_display_mode *adjusted_mode) | ||
842 | { | ||
843 | struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); | ||
844 | struct drm_crtc *crtc = encoder->crtc; | ||
845 | struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); | ||
846 | struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; | ||
847 | struct drm_device *dev = encoder->dev; | ||
848 | |||
849 | intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; | ||
850 | intel_dp->DP |= intel_dp->color_range; | ||
851 | |||
852 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | ||
853 | intel_dp->DP |= DP_SYNC_HS_HIGH; | ||
854 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | ||
855 | intel_dp->DP |= DP_SYNC_VS_HIGH; | ||
856 | |||
857 | intel_dp->DP |= DP_LINK_TRAIN_OFF; | ||
858 | |||
859 | switch (intel_dp->lane_count) { | ||
860 | case 1: | ||
861 | intel_dp->DP |= DP_PORT_WIDTH_1; | ||
862 | break; | ||
863 | case 2: | ||
864 | intel_dp->DP |= DP_PORT_WIDTH_2; | ||
865 | break; | ||
866 | case 4: | ||
867 | intel_dp->DP |= DP_PORT_WIDTH_4; | ||
868 | break; | ||
869 | } | ||
870 | if (intel_dp->has_audio) | ||
871 | intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; | ||
872 | |||
873 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | ||
874 | intel_dp->link_configuration[0] = intel_dp->link_bw; | ||
875 | intel_dp->link_configuration[1] = intel_dp->lane_count; | ||
876 | |||
877 | /* | ||
878 | * Check for DPCD version > 1.1 and enhanced framing support | ||
879 | */ | ||
880 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && | ||
881 | (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { | ||
882 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | ||
883 | intel_dp->DP |= DP_ENHANCED_FRAMING; | ||
884 | } | ||
885 | |||
886 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ | ||
887 | if (intel_crtc->pipe == 1) | ||
888 | intel_dp->DP |= DP_PIPEB_SELECT; | ||
889 | |||
890 | REG_WRITE(intel_dp->output_reg, (intel_dp->DP | DP_PORT_EN)); | ||
891 | DRM_DEBUG_KMS("DP expected reg is %x\n", intel_dp->DP); | ||
892 | if (is_edp(intel_encoder)) { | ||
893 | uint32_t pfit_control; | ||
894 | cdv_intel_edp_panel_on(intel_encoder); | ||
895 | |||
896 | if (mode->hdisplay != adjusted_mode->hdisplay || | ||
897 | mode->vdisplay != adjusted_mode->vdisplay) | ||
898 | pfit_control = PFIT_ENABLE; | ||
899 | else | ||
900 | pfit_control = 0; | ||
901 | |||
902 | pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT; | ||
903 | |||
904 | REG_WRITE(PFIT_CONTROL, pfit_control); | ||
905 | } | ||
906 | } | ||
907 | |||
908 | |||
909 | /* If the sink supports it, try to set the power state appropriately */ | ||
910 | static void cdv_intel_dp_sink_dpms(struct psb_intel_encoder *encoder, int mode) | ||
911 | { | ||
912 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
913 | int ret, i; | ||
914 | |||
915 | /* Should have a valid DPCD by this point */ | ||
916 | if (intel_dp->dpcd[DP_DPCD_REV] < 0x11) | ||
917 | return; | ||
918 | |||
919 | if (mode != DRM_MODE_DPMS_ON) { | ||
920 | ret = cdv_intel_dp_aux_native_write_1(encoder, DP_SET_POWER, | ||
921 | DP_SET_POWER_D3); | ||
922 | if (ret != 1) | ||
923 | DRM_DEBUG_DRIVER("failed to write sink power state\n"); | ||
924 | } else { | ||
925 | /* | ||
926 | * When turning on, we need to retry for 1ms to give the sink | ||
927 | * time to wake up. | ||
928 | */ | ||
929 | for (i = 0; i < 3; i++) { | ||
930 | ret = cdv_intel_dp_aux_native_write_1(encoder, | ||
931 | DP_SET_POWER, | ||
932 | DP_SET_POWER_D0); | ||
933 | if (ret == 1) | ||
934 | break; | ||
935 | udelay(1000); | ||
936 | } | ||
937 | } | ||
938 | } | ||
939 | |||
940 | static void cdv_intel_dp_prepare(struct drm_encoder *encoder) | ||
941 | { | ||
942 | struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); | ||
943 | int edp = is_edp(intel_encoder); | ||
944 | |||
945 | if (edp) { | ||
946 | cdv_intel_edp_backlight_off(intel_encoder); | ||
947 | cdv_intel_edp_panel_off(intel_encoder); | ||
948 | cdv_intel_edp_panel_vdd_on(intel_encoder); | ||
949 | } | ||
950 | /* Wake up the sink first */ | ||
951 | cdv_intel_dp_sink_dpms(intel_encoder, DRM_MODE_DPMS_ON); | ||
952 | cdv_intel_dp_link_down(intel_encoder); | ||
953 | if (edp) | ||
954 | cdv_intel_edp_panel_vdd_off(intel_encoder); | ||
955 | } | ||
956 | |||
957 | static void cdv_intel_dp_commit(struct drm_encoder *encoder) | ||
958 | { | ||
959 | struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); | ||
960 | int edp = is_edp(intel_encoder); | ||
961 | |||
962 | if (edp) | ||
963 | cdv_intel_edp_panel_on(intel_encoder); | ||
964 | cdv_intel_dp_start_link_train(intel_encoder); | ||
965 | cdv_intel_dp_complete_link_train(intel_encoder); | ||
966 | if (edp) | ||
967 | cdv_intel_edp_backlight_on(intel_encoder); | ||
968 | } | ||
969 | |||
970 | static void | ||
971 | cdv_intel_dp_dpms(struct drm_encoder *encoder, int mode) | ||
972 | { | ||
973 | struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); | ||
974 | struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; | ||
975 | struct drm_device *dev = encoder->dev; | ||
976 | uint32_t dp_reg = REG_READ(intel_dp->output_reg); | ||
977 | int edp = is_edp(intel_encoder); | ||
978 | |||
979 | if (mode != DRM_MODE_DPMS_ON) { | ||
980 | if (edp) { | ||
981 | cdv_intel_edp_backlight_off(intel_encoder); | ||
982 | cdv_intel_edp_panel_vdd_on(intel_encoder); | ||
983 | } | ||
984 | cdv_intel_dp_sink_dpms(intel_encoder, mode); | ||
985 | cdv_intel_dp_link_down(intel_encoder); | ||
986 | if (edp) { | ||
987 | cdv_intel_edp_panel_vdd_off(intel_encoder); | ||
988 | cdv_intel_edp_panel_off(intel_encoder); | ||
989 | } | ||
990 | } else { | ||
991 | if (edp) | ||
992 | cdv_intel_edp_panel_on(intel_encoder); | ||
993 | cdv_intel_dp_sink_dpms(intel_encoder, mode); | ||
994 | if (!(dp_reg & DP_PORT_EN)) { | ||
995 | cdv_intel_dp_start_link_train(intel_encoder); | ||
996 | cdv_intel_dp_complete_link_train(intel_encoder); | ||
997 | } | ||
998 | if (edp) | ||
999 | cdv_intel_edp_backlight_on(intel_encoder); | ||
1000 | } | ||
1001 | } | ||
1002 | |||
1003 | /* | ||
1004 | * Native read with retry for link status and receiver capability reads for | ||
1005 | * cases where the sink may still be asleep. | ||
1006 | */ | ||
1007 | static bool | ||
1008 | cdv_intel_dp_aux_native_read_retry(struct psb_intel_encoder *encoder, uint16_t address, | ||
1009 | uint8_t *recv, int recv_bytes) | ||
1010 | { | ||
1011 | int ret, i; | ||
1012 | |||
1013 | /* | ||
1014 | * Sinks are *supposed* to come up within 1ms from an off state, | ||
1015 | * but we're also supposed to retry 3 times per the spec. | ||
1016 | */ | ||
1017 | for (i = 0; i < 3; i++) { | ||
1018 | ret = cdv_intel_dp_aux_native_read(encoder, address, recv, | ||
1019 | recv_bytes); | ||
1020 | if (ret == recv_bytes) | ||
1021 | return true; | ||
1022 | udelay(1000); | ||
1023 | } | ||
1024 | |||
1025 | return false; | ||
1026 | } | ||
1027 | |||
1028 | /* | ||
1029 | * Fetch AUX CH registers 0x202 - 0x207 which contain | ||
1030 | * link status information | ||
1031 | */ | ||
1032 | static bool | ||
1033 | cdv_intel_dp_get_link_status(struct psb_intel_encoder *encoder) | ||
1034 | { | ||
1035 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1036 | return cdv_intel_dp_aux_native_read_retry(encoder, | ||
1037 | DP_LANE0_1_STATUS, | ||
1038 | intel_dp->link_status, | ||
1039 | DP_LINK_STATUS_SIZE); | ||
1040 | } | ||
1041 | |||
1042 | static uint8_t | ||
1043 | cdv_intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
1044 | int r) | ||
1045 | { | ||
1046 | return link_status[r - DP_LANE0_1_STATUS]; | ||
1047 | } | ||
1048 | |||
1049 | static uint8_t | ||
1050 | cdv_intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
1051 | int lane) | ||
1052 | { | ||
1053 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
1054 | int s = ((lane & 1) ? | ||
1055 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : | ||
1056 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); | ||
1057 | uint8_t l = cdv_intel_dp_link_status(link_status, i); | ||
1058 | |||
1059 | return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; | ||
1060 | } | ||
1061 | |||
1062 | static uint8_t | ||
1063 | cdv_intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
1064 | int lane) | ||
1065 | { | ||
1066 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
1067 | int s = ((lane & 1) ? | ||
1068 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : | ||
1069 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); | ||
1070 | uint8_t l = cdv_intel_dp_link_status(link_status, i); | ||
1071 | |||
1072 | return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; | ||
1073 | } | ||
1074 | |||
1075 | |||
1076 | #if 0 | ||
1077 | static char *voltage_names[] = { | ||
1078 | "0.4V", "0.6V", "0.8V", "1.2V" | ||
1079 | }; | ||
1080 | static char *pre_emph_names[] = { | ||
1081 | "0dB", "3.5dB", "6dB", "9.5dB" | ||
1082 | }; | ||
1083 | static char *link_train_names[] = { | ||
1084 | "pattern 1", "pattern 2", "idle", "off" | ||
1085 | }; | ||
1086 | #endif | ||
1087 | |||
1088 | #define CDV_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_1200 | ||
1089 | /* | ||
1090 | static uint8_t | ||
1091 | cdv_intel_dp_pre_emphasis_max(uint8_t voltage_swing) | ||
1092 | { | ||
1093 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
1094 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
1095 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
1096 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
1097 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
1098 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
1099 | return DP_TRAIN_PRE_EMPHASIS_3_5; | ||
1100 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
1101 | default: | ||
1102 | return DP_TRAIN_PRE_EMPHASIS_0; | ||
1103 | } | ||
1104 | } | ||
1105 | */ | ||
1106 | static void | ||
1107 | cdv_intel_get_adjust_train(struct psb_intel_encoder *encoder) | ||
1108 | { | ||
1109 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1110 | uint8_t v = 0; | ||
1111 | uint8_t p = 0; | ||
1112 | int lane; | ||
1113 | |||
1114 | for (lane = 0; lane < intel_dp->lane_count; lane++) { | ||
1115 | uint8_t this_v = cdv_intel_get_adjust_request_voltage(intel_dp->link_status, lane); | ||
1116 | uint8_t this_p = cdv_intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane); | ||
1117 | |||
1118 | if (this_v > v) | ||
1119 | v = this_v; | ||
1120 | if (this_p > p) | ||
1121 | p = this_p; | ||
1122 | } | ||
1123 | |||
1124 | if (v >= CDV_DP_VOLTAGE_MAX) | ||
1125 | v = CDV_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; | ||
1126 | |||
1127 | if (p == DP_TRAIN_PRE_EMPHASIS_MASK) | ||
1128 | p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | ||
1129 | |||
1130 | for (lane = 0; lane < 4; lane++) | ||
1131 | intel_dp->train_set[lane] = v | p; | ||
1132 | } | ||
1133 | |||
1134 | |||
1135 | static uint8_t | ||
1136 | cdv_intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
1137 | int lane) | ||
1138 | { | ||
1139 | int i = DP_LANE0_1_STATUS + (lane >> 1); | ||
1140 | int s = (lane & 1) * 4; | ||
1141 | uint8_t l = cdv_intel_dp_link_status(link_status, i); | ||
1142 | |||
1143 | return (l >> s) & 0xf; | ||
1144 | } | ||
1145 | |||
1146 | /* Check for clock recovery is done on all channels */ | ||
1147 | static bool | ||
1148 | cdv_intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | ||
1149 | { | ||
1150 | int lane; | ||
1151 | uint8_t lane_status; | ||
1152 | |||
1153 | for (lane = 0; lane < lane_count; lane++) { | ||
1154 | lane_status = cdv_intel_get_lane_status(link_status, lane); | ||
1155 | if ((lane_status & DP_LANE_CR_DONE) == 0) | ||
1156 | return false; | ||
1157 | } | ||
1158 | return true; | ||
1159 | } | ||
1160 | |||
1161 | /* Check to see if channel eq is done on all channels */ | ||
1162 | #define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\ | ||
1163 | DP_LANE_CHANNEL_EQ_DONE|\ | ||
1164 | DP_LANE_SYMBOL_LOCKED) | ||
1165 | static bool | ||
1166 | cdv_intel_channel_eq_ok(struct psb_intel_encoder *encoder) | ||
1167 | { | ||
1168 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1169 | uint8_t lane_align; | ||
1170 | uint8_t lane_status; | ||
1171 | int lane; | ||
1172 | |||
1173 | lane_align = cdv_intel_dp_link_status(intel_dp->link_status, | ||
1174 | DP_LANE_ALIGN_STATUS_UPDATED); | ||
1175 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | ||
1176 | return false; | ||
1177 | for (lane = 0; lane < intel_dp->lane_count; lane++) { | ||
1178 | lane_status = cdv_intel_get_lane_status(intel_dp->link_status, lane); | ||
1179 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) | ||
1180 | return false; | ||
1181 | } | ||
1182 | return true; | ||
1183 | } | ||
1184 | |||
1185 | static bool | ||
1186 | cdv_intel_dp_set_link_train(struct psb_intel_encoder *encoder, | ||
1187 | uint32_t dp_reg_value, | ||
1188 | uint8_t dp_train_pat) | ||
1189 | { | ||
1190 | |||
1191 | struct drm_device *dev = encoder->base.dev; | ||
1192 | int ret; | ||
1193 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1194 | |||
1195 | REG_WRITE(intel_dp->output_reg, dp_reg_value); | ||
1196 | REG_READ(intel_dp->output_reg); | ||
1197 | |||
1198 | ret = cdv_intel_dp_aux_native_write_1(encoder, | ||
1199 | DP_TRAINING_PATTERN_SET, | ||
1200 | dp_train_pat); | ||
1201 | |||
1202 | if (ret != 1) { | ||
1203 | DRM_DEBUG_KMS("Failure in setting link pattern %x\n", | ||
1204 | dp_train_pat); | ||
1205 | return false; | ||
1206 | } | ||
1207 | |||
1208 | return true; | ||
1209 | } | ||
1210 | |||
1211 | |||
1212 | static bool | ||
1213 | cdv_intel_dplink_set_level(struct psb_intel_encoder *encoder, | ||
1214 | uint8_t dp_train_pat) | ||
1215 | { | ||
1216 | |||
1217 | int ret; | ||
1218 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1219 | |||
1220 | ret = cdv_intel_dp_aux_native_write(encoder, | ||
1221 | DP_TRAINING_LANE0_SET, | ||
1222 | intel_dp->train_set, | ||
1223 | intel_dp->lane_count); | ||
1224 | |||
1225 | if (ret != intel_dp->lane_count) { | ||
1226 | DRM_DEBUG_KMS("Failure in setting level %d, lane_cnt= %d\n", | ||
1227 | intel_dp->train_set[0], intel_dp->lane_count); | ||
1228 | return false; | ||
1229 | } | ||
1230 | return true; | ||
1231 | } | ||
1232 | |||
1233 | static void | ||
1234 | cdv_intel_dp_set_vswing_premph(struct psb_intel_encoder *encoder, uint8_t signal_level) | ||
1235 | { | ||
1236 | struct drm_device *dev = encoder->base.dev; | ||
1237 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1238 | struct ddi_regoff *ddi_reg; | ||
1239 | int vswing, premph, index; | ||
1240 | |||
1241 | if (intel_dp->output_reg == DP_B) | ||
1242 | ddi_reg = &ddi_DP_train_table[0]; | ||
1243 | else | ||
1244 | ddi_reg = &ddi_DP_train_table[1]; | ||
1245 | |||
1246 | vswing = (signal_level & DP_TRAIN_VOLTAGE_SWING_MASK); | ||
1247 | premph = ((signal_level & DP_TRAIN_PRE_EMPHASIS_MASK)) >> | ||
1248 | DP_TRAIN_PRE_EMPHASIS_SHIFT; | ||
1249 | |||
1250 | if (vswing + premph > 3) | ||
1251 | return; | ||
1252 | #ifdef CDV_FAST_LINK_TRAIN | ||
1253 | return; | ||
1254 | #endif | ||
1255 | DRM_DEBUG_KMS("Test2\n"); | ||
1256 | //return ; | ||
1257 | cdv_sb_reset(dev); | ||
1258 | /* ;Swing voltage programming | ||
1259 | ;gfx_dpio_set_reg(0xc058, 0x0505313A) */ | ||
1260 | cdv_sb_write(dev, ddi_reg->VSwing5, 0x0505313A); | ||
1261 | |||
1262 | /* ;gfx_dpio_set_reg(0x8154, 0x43406055) */ | ||
1263 | cdv_sb_write(dev, ddi_reg->VSwing1, 0x43406055); | ||
1264 | |||
1265 | /* ;gfx_dpio_set_reg(0x8148, 0x55338954) | ||
1266 | * The VSwing_PreEmph table is also considered based on the vswing/premp | ||
1267 | */ | ||
1268 | index = (vswing + premph) * 2; | ||
1269 | if (premph == 1 && vswing == 1) { | ||
1270 | cdv_sb_write(dev, ddi_reg->VSwing2, 0x055738954); | ||
1271 | } else | ||
1272 | cdv_sb_write(dev, ddi_reg->VSwing2, dp_vswing_premph_table[index]); | ||
1273 | |||
1274 | /* ;gfx_dpio_set_reg(0x814c, 0x40802040) */ | ||
1275 | if ((vswing + premph) == DP_TRAIN_VOLTAGE_SWING_1200) | ||
1276 | cdv_sb_write(dev, ddi_reg->VSwing3, 0x70802040); | ||
1277 | else | ||
1278 | cdv_sb_write(dev, ddi_reg->VSwing3, 0x40802040); | ||
1279 | |||
1280 | /* ;gfx_dpio_set_reg(0x8150, 0x2b405555) */ | ||
1281 | /* cdv_sb_write(dev, ddi_reg->VSwing4, 0x2b405555); */ | ||
1282 | |||
1283 | /* ;gfx_dpio_set_reg(0x8154, 0xc3406055) */ | ||
1284 | cdv_sb_write(dev, ddi_reg->VSwing1, 0xc3406055); | ||
1285 | |||
1286 | /* ;Pre emphasis programming | ||
1287 | * ;gfx_dpio_set_reg(0xc02c, 0x1f030040) | ||
1288 | */ | ||
1289 | cdv_sb_write(dev, ddi_reg->PreEmph1, 0x1f030040); | ||
1290 | |||
1291 | /* ;gfx_dpio_set_reg(0x8124, 0x00004000) */ | ||
1292 | index = 2 * premph + 1; | ||
1293 | cdv_sb_write(dev, ddi_reg->PreEmph2, dp_vswing_premph_table[index]); | ||
1294 | return; | ||
1295 | } | ||
1296 | |||
1297 | |||
1298 | /* Enable corresponding port and start training pattern 1 */ | ||
1299 | static void | ||
1300 | cdv_intel_dp_start_link_train(struct psb_intel_encoder *encoder) | ||
1301 | { | ||
1302 | struct drm_device *dev = encoder->base.dev; | ||
1303 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1304 | int i; | ||
1305 | uint8_t voltage; | ||
1306 | bool clock_recovery = false; | ||
1307 | int tries; | ||
1308 | u32 reg; | ||
1309 | uint32_t DP = intel_dp->DP; | ||
1310 | |||
1311 | DP |= DP_PORT_EN; | ||
1312 | DP &= ~DP_LINK_TRAIN_MASK; | ||
1313 | |||
1314 | reg = DP; | ||
1315 | reg |= DP_LINK_TRAIN_PAT_1; | ||
1316 | /* Enable output, wait for it to become active */ | ||
1317 | REG_WRITE(intel_dp->output_reg, reg); | ||
1318 | REG_READ(intel_dp->output_reg); | ||
1319 | psb_intel_wait_for_vblank(dev); | ||
1320 | |||
1321 | DRM_DEBUG_KMS("Link config\n"); | ||
1322 | /* Write the link configuration data */ | ||
1323 | cdv_intel_dp_aux_native_write(encoder, DP_LINK_BW_SET, | ||
1324 | intel_dp->link_configuration, | ||
1325 | 2); | ||
1326 | |||
1327 | memset(intel_dp->train_set, 0, 4); | ||
1328 | voltage = 0; | ||
1329 | tries = 0; | ||
1330 | clock_recovery = false; | ||
1331 | |||
1332 | DRM_DEBUG_KMS("Start train\n"); | ||
1333 | reg = DP | DP_LINK_TRAIN_PAT_1; | ||
1334 | |||
1335 | |||
1336 | for (;;) { | ||
1337 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ | ||
1338 | DRM_DEBUG_KMS("DP Link Train Set %x, Link_config %x, %x\n", | ||
1339 | intel_dp->train_set[0], | ||
1340 | intel_dp->link_configuration[0], | ||
1341 | intel_dp->link_configuration[1]); | ||
1342 | |||
1343 | if (!cdv_intel_dp_set_link_train(encoder, reg, DP_TRAINING_PATTERN_1)) { | ||
1344 | DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 1\n"); | ||
1345 | } | ||
1346 | cdv_intel_dp_set_vswing_premph(encoder, intel_dp->train_set[0]); | ||
1347 | /* Set training pattern 1 */ | ||
1348 | |||
1349 | cdv_intel_dplink_set_level(encoder, DP_TRAINING_PATTERN_1); | ||
1350 | |||
1351 | udelay(200); | ||
1352 | if (!cdv_intel_dp_get_link_status(encoder)) | ||
1353 | break; | ||
1354 | |||
1355 | DRM_DEBUG_KMS("DP Link status %x, %x, %x, %x, %x, %x\n", | ||
1356 | intel_dp->link_status[0], intel_dp->link_status[1], intel_dp->link_status[2], | ||
1357 | intel_dp->link_status[3], intel_dp->link_status[4], intel_dp->link_status[5]); | ||
1358 | |||
1359 | if (cdv_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | ||
1360 | DRM_DEBUG_KMS("PT1 train is done\n"); | ||
1361 | clock_recovery = true; | ||
1362 | break; | ||
1363 | } | ||
1364 | |||
1365 | /* Check to see if we've tried the max voltage */ | ||
1366 | for (i = 0; i < intel_dp->lane_count; i++) | ||
1367 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | ||
1368 | break; | ||
1369 | if (i == intel_dp->lane_count) | ||
1370 | break; | ||
1371 | |||
1372 | /* Check to see if we've tried the same voltage 5 times */ | ||
1373 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | ||
1374 | ++tries; | ||
1375 | if (tries == 5) | ||
1376 | break; | ||
1377 | } else | ||
1378 | tries = 0; | ||
1379 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
1380 | |||
1381 | /* Compute new intel_dp->train_set as requested by target */ | ||
1382 | cdv_intel_get_adjust_train(encoder); | ||
1383 | |||
1384 | } | ||
1385 | |||
1386 | if (!clock_recovery) { | ||
1387 | DRM_DEBUG_KMS("failure in DP patter 1 training, train set %x\n", intel_dp->train_set[0]); | ||
1388 | } | ||
1389 | |||
1390 | intel_dp->DP = DP; | ||
1391 | } | ||
1392 | |||
1393 | static void | ||
1394 | cdv_intel_dp_complete_link_train(struct psb_intel_encoder *encoder) | ||
1395 | { | ||
1396 | struct drm_device *dev = encoder->base.dev; | ||
1397 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1398 | bool channel_eq = false; | ||
1399 | int tries, cr_tries; | ||
1400 | u32 reg; | ||
1401 | uint32_t DP = intel_dp->DP; | ||
1402 | |||
1403 | /* channel equalization */ | ||
1404 | tries = 0; | ||
1405 | cr_tries = 0; | ||
1406 | channel_eq = false; | ||
1407 | |||
1408 | DRM_DEBUG_KMS("\n"); | ||
1409 | reg = DP | DP_LINK_TRAIN_PAT_2; | ||
1410 | |||
1411 | for (;;) { | ||
1412 | |||
1413 | DRM_DEBUG_KMS("DP Link Train Set %x, Link_config %x, %x\n", | ||
1414 | intel_dp->train_set[0], | ||
1415 | intel_dp->link_configuration[0], | ||
1416 | intel_dp->link_configuration[1]); | ||
1417 | /* channel eq pattern */ | ||
1418 | |||
1419 | if (!cdv_intel_dp_set_link_train(encoder, reg, | ||
1420 | DP_TRAINING_PATTERN_2)) { | ||
1421 | DRM_DEBUG_KMS("Failure in aux-transfer setting pattern 2\n"); | ||
1422 | } | ||
1423 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ | ||
1424 | |||
1425 | if (cr_tries > 5) { | ||
1426 | DRM_ERROR("failed to train DP, aborting\n"); | ||
1427 | cdv_intel_dp_link_down(encoder); | ||
1428 | break; | ||
1429 | } | ||
1430 | |||
1431 | cdv_intel_dp_set_vswing_premph(encoder, intel_dp->train_set[0]); | ||
1432 | |||
1433 | cdv_intel_dplink_set_level(encoder, DP_TRAINING_PATTERN_2); | ||
1434 | |||
1435 | udelay(1000); | ||
1436 | if (!cdv_intel_dp_get_link_status(encoder)) | ||
1437 | break; | ||
1438 | |||
1439 | DRM_DEBUG_KMS("DP Link status %x, %x, %x, %x, %x, %x\n", | ||
1440 | intel_dp->link_status[0], intel_dp->link_status[1], intel_dp->link_status[2], | ||
1441 | intel_dp->link_status[3], intel_dp->link_status[4], intel_dp->link_status[5]); | ||
1442 | |||
1443 | /* Make sure clock is still ok */ | ||
1444 | if (!cdv_intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | ||
1445 | cdv_intel_dp_start_link_train(encoder); | ||
1446 | cr_tries++; | ||
1447 | continue; | ||
1448 | } | ||
1449 | |||
1450 | if (cdv_intel_channel_eq_ok(encoder)) { | ||
1451 | DRM_DEBUG_KMS("PT2 train is done\n"); | ||
1452 | channel_eq = true; | ||
1453 | break; | ||
1454 | } | ||
1455 | |||
1456 | /* Try 5 times, then try clock recovery if that fails */ | ||
1457 | if (tries > 5) { | ||
1458 | cdv_intel_dp_link_down(encoder); | ||
1459 | cdv_intel_dp_start_link_train(encoder); | ||
1460 | tries = 0; | ||
1461 | cr_tries++; | ||
1462 | continue; | ||
1463 | } | ||
1464 | |||
1465 | /* Compute new intel_dp->train_set as requested by target */ | ||
1466 | cdv_intel_get_adjust_train(encoder); | ||
1467 | ++tries; | ||
1468 | |||
1469 | } | ||
1470 | |||
1471 | reg = DP | DP_LINK_TRAIN_OFF; | ||
1472 | |||
1473 | REG_WRITE(intel_dp->output_reg, reg); | ||
1474 | REG_READ(intel_dp->output_reg); | ||
1475 | cdv_intel_dp_aux_native_write_1(encoder, | ||
1476 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); | ||
1477 | } | ||
1478 | |||
1479 | static void | ||
1480 | cdv_intel_dp_link_down(struct psb_intel_encoder *encoder) | ||
1481 | { | ||
1482 | struct drm_device *dev = encoder->base.dev; | ||
1483 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1484 | uint32_t DP = intel_dp->DP; | ||
1485 | |||
1486 | if ((REG_READ(intel_dp->output_reg) & DP_PORT_EN) == 0) | ||
1487 | return; | ||
1488 | |||
1489 | DRM_DEBUG_KMS("\n"); | ||
1490 | |||
1491 | |||
1492 | { | ||
1493 | DP &= ~DP_LINK_TRAIN_MASK; | ||
1494 | REG_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | ||
1495 | } | ||
1496 | REG_READ(intel_dp->output_reg); | ||
1497 | |||
1498 | msleep(17); | ||
1499 | |||
1500 | REG_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); | ||
1501 | REG_READ(intel_dp->output_reg); | ||
1502 | } | ||
1503 | |||
1504 | static enum drm_connector_status | ||
1505 | cdv_dp_detect(struct psb_intel_encoder *encoder) | ||
1506 | { | ||
1507 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1508 | enum drm_connector_status status; | ||
1509 | |||
1510 | status = connector_status_disconnected; | ||
1511 | if (cdv_intel_dp_aux_native_read(encoder, 0x000, intel_dp->dpcd, | ||
1512 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) | ||
1513 | { | ||
1514 | if (intel_dp->dpcd[DP_DPCD_REV] != 0) | ||
1515 | status = connector_status_connected; | ||
1516 | } | ||
1517 | if (status == connector_status_connected) | ||
1518 | DRM_DEBUG_KMS("DPCD: Rev=%x LN_Rate=%x LN_CNT=%x LN_DOWNSP=%x\n", | ||
1519 | intel_dp->dpcd[0], intel_dp->dpcd[1], | ||
1520 | intel_dp->dpcd[2], intel_dp->dpcd[3]); | ||
1521 | return status; | ||
1522 | } | ||
1523 | |||
1524 | /** | ||
1525 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. | ||
1526 | * | ||
1527 | * \return true if DP port is connected. | ||
1528 | * \return false if DP port is disconnected. | ||
1529 | */ | ||
1530 | static enum drm_connector_status | ||
1531 | cdv_intel_dp_detect(struct drm_connector *connector, bool force) | ||
1532 | { | ||
1533 | struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector); | ||
1534 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1535 | enum drm_connector_status status; | ||
1536 | struct edid *edid = NULL; | ||
1537 | int edp = is_edp(encoder); | ||
1538 | |||
1539 | intel_dp->has_audio = false; | ||
1540 | |||
1541 | if (edp) | ||
1542 | cdv_intel_edp_panel_vdd_on(encoder); | ||
1543 | status = cdv_dp_detect(encoder); | ||
1544 | if (status != connector_status_connected) { | ||
1545 | if (edp) | ||
1546 | cdv_intel_edp_panel_vdd_off(encoder); | ||
1547 | return status; | ||
1548 | } | ||
1549 | |||
1550 | if (intel_dp->force_audio) { | ||
1551 | intel_dp->has_audio = intel_dp->force_audio > 0; | ||
1552 | } else { | ||
1553 | edid = drm_get_edid(connector, &intel_dp->adapter); | ||
1554 | if (edid) { | ||
1555 | intel_dp->has_audio = drm_detect_monitor_audio(edid); | ||
1556 | kfree(edid); | ||
1557 | } | ||
1558 | } | ||
1559 | if (edp) | ||
1560 | cdv_intel_edp_panel_vdd_off(encoder); | ||
1561 | |||
1562 | return connector_status_connected; | ||
1563 | } | ||
1564 | |||
1565 | static int cdv_intel_dp_get_modes(struct drm_connector *connector) | ||
1566 | { | ||
1567 | struct psb_intel_encoder *intel_encoder = psb_intel_attached_encoder(connector); | ||
1568 | struct cdv_intel_dp *intel_dp = intel_encoder->dev_priv; | ||
1569 | struct edid *edid = NULL; | ||
1570 | int ret = 0; | ||
1571 | int edp = is_edp(intel_encoder); | ||
1572 | |||
1573 | |||
1574 | edid = drm_get_edid(connector, &intel_dp->adapter); | ||
1575 | if (edid) { | ||
1576 | drm_mode_connector_update_edid_property(connector, edid); | ||
1577 | ret = drm_add_edid_modes(connector, edid); | ||
1578 | kfree(edid); | ||
1579 | } | ||
1580 | |||
1581 | if (is_edp(intel_encoder)) { | ||
1582 | struct drm_device *dev = connector->dev; | ||
1583 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
1584 | |||
1585 | cdv_intel_edp_panel_vdd_off(intel_encoder); | ||
1586 | if (ret) { | ||
1587 | if (edp && !intel_dp->panel_fixed_mode) { | ||
1588 | struct drm_display_mode *newmode; | ||
1589 | list_for_each_entry(newmode, &connector->probed_modes, | ||
1590 | head) { | ||
1591 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | ||
1592 | intel_dp->panel_fixed_mode = | ||
1593 | drm_mode_duplicate(dev, newmode); | ||
1594 | break; | ||
1595 | } | ||
1596 | } | ||
1597 | } | ||
1598 | |||
1599 | return ret; | ||
1600 | } | ||
1601 | if (!intel_dp->panel_fixed_mode && dev_priv->lfp_lvds_vbt_mode) { | ||
1602 | intel_dp->panel_fixed_mode = | ||
1603 | drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); | ||
1604 | if (intel_dp->panel_fixed_mode) { | ||
1605 | intel_dp->panel_fixed_mode->type |= | ||
1606 | DRM_MODE_TYPE_PREFERRED; | ||
1607 | } | ||
1608 | } | ||
1609 | if (intel_dp->panel_fixed_mode != NULL) { | ||
1610 | struct drm_display_mode *mode; | ||
1611 | mode = drm_mode_duplicate(dev, intel_dp->panel_fixed_mode); | ||
1612 | drm_mode_probed_add(connector, mode); | ||
1613 | return 1; | ||
1614 | } | ||
1615 | } | ||
1616 | |||
1617 | return ret; | ||
1618 | } | ||
1619 | |||
1620 | static bool | ||
1621 | cdv_intel_dp_detect_audio(struct drm_connector *connector) | ||
1622 | { | ||
1623 | struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector); | ||
1624 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1625 | struct edid *edid; | ||
1626 | bool has_audio = false; | ||
1627 | int edp = is_edp(encoder); | ||
1628 | |||
1629 | if (edp) | ||
1630 | cdv_intel_edp_panel_vdd_on(encoder); | ||
1631 | |||
1632 | edid = drm_get_edid(connector, &intel_dp->adapter); | ||
1633 | if (edid) { | ||
1634 | has_audio = drm_detect_monitor_audio(edid); | ||
1635 | kfree(edid); | ||
1636 | } | ||
1637 | if (edp) | ||
1638 | cdv_intel_edp_panel_vdd_off(encoder); | ||
1639 | |||
1640 | return has_audio; | ||
1641 | } | ||
1642 | |||
1643 | static int | ||
1644 | cdv_intel_dp_set_property(struct drm_connector *connector, | ||
1645 | struct drm_property *property, | ||
1646 | uint64_t val) | ||
1647 | { | ||
1648 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
1649 | struct psb_intel_encoder *encoder = psb_intel_attached_encoder(connector); | ||
1650 | struct cdv_intel_dp *intel_dp = encoder->dev_priv; | ||
1651 | int ret; | ||
1652 | |||
1653 | ret = drm_connector_property_set_value(connector, property, val); | ||
1654 | if (ret) | ||
1655 | return ret; | ||
1656 | |||
1657 | if (property == dev_priv->force_audio_property) { | ||
1658 | int i = val; | ||
1659 | bool has_audio; | ||
1660 | |||
1661 | if (i == intel_dp->force_audio) | ||
1662 | return 0; | ||
1663 | |||
1664 | intel_dp->force_audio = i; | ||
1665 | |||
1666 | if (i == 0) | ||
1667 | has_audio = cdv_intel_dp_detect_audio(connector); | ||
1668 | else | ||
1669 | has_audio = i > 0; | ||
1670 | |||
1671 | if (has_audio == intel_dp->has_audio) | ||
1672 | return 0; | ||
1673 | |||
1674 | intel_dp->has_audio = has_audio; | ||
1675 | goto done; | ||
1676 | } | ||
1677 | |||
1678 | if (property == dev_priv->broadcast_rgb_property) { | ||
1679 | if (val == !!intel_dp->color_range) | ||
1680 | return 0; | ||
1681 | |||
1682 | intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0; | ||
1683 | goto done; | ||
1684 | } | ||
1685 | |||
1686 | return -EINVAL; | ||
1687 | |||
1688 | done: | ||
1689 | if (encoder->base.crtc) { | ||
1690 | struct drm_crtc *crtc = encoder->base.crtc; | ||
1691 | drm_crtc_helper_set_mode(crtc, &crtc->mode, | ||
1692 | crtc->x, crtc->y, | ||
1693 | crtc->fb); | ||
1694 | } | ||
1695 | |||
1696 | return 0; | ||
1697 | } | ||
1698 | |||
1699 | static void | ||
1700 | cdv_intel_dp_destroy(struct drm_connector *connector) | ||
1701 | { | ||
1702 | struct psb_intel_encoder *psb_intel_encoder = | ||
1703 | psb_intel_attached_encoder(connector); | ||
1704 | struct cdv_intel_dp *intel_dp = psb_intel_encoder->dev_priv; | ||
1705 | |||
1706 | if (is_edp(psb_intel_encoder)) { | ||
1707 | /* cdv_intel_panel_destroy_backlight(connector->dev); */ | ||
1708 | if (intel_dp->panel_fixed_mode) { | ||
1709 | kfree(intel_dp->panel_fixed_mode); | ||
1710 | intel_dp->panel_fixed_mode = NULL; | ||
1711 | } | ||
1712 | } | ||
1713 | i2c_del_adapter(&intel_dp->adapter); | ||
1714 | drm_sysfs_connector_remove(connector); | ||
1715 | drm_connector_cleanup(connector); | ||
1716 | kfree(connector); | ||
1717 | } | ||
1718 | |||
1719 | static void cdv_intel_dp_encoder_destroy(struct drm_encoder *encoder) | ||
1720 | { | ||
1721 | drm_encoder_cleanup(encoder); | ||
1722 | } | ||
1723 | |||
1724 | static const struct drm_encoder_helper_funcs cdv_intel_dp_helper_funcs = { | ||
1725 | .dpms = cdv_intel_dp_dpms, | ||
1726 | .mode_fixup = cdv_intel_dp_mode_fixup, | ||
1727 | .prepare = cdv_intel_dp_prepare, | ||
1728 | .mode_set = cdv_intel_dp_mode_set, | ||
1729 | .commit = cdv_intel_dp_commit, | ||
1730 | }; | ||
1731 | |||
1732 | static const struct drm_connector_funcs cdv_intel_dp_connector_funcs = { | ||
1733 | .dpms = drm_helper_connector_dpms, | ||
1734 | .detect = cdv_intel_dp_detect, | ||
1735 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
1736 | .set_property = cdv_intel_dp_set_property, | ||
1737 | .destroy = cdv_intel_dp_destroy, | ||
1738 | }; | ||
1739 | |||
1740 | static const struct drm_connector_helper_funcs cdv_intel_dp_connector_helper_funcs = { | ||
1741 | .get_modes = cdv_intel_dp_get_modes, | ||
1742 | .mode_valid = cdv_intel_dp_mode_valid, | ||
1743 | .best_encoder = psb_intel_best_encoder, | ||
1744 | }; | ||
1745 | |||
1746 | static const struct drm_encoder_funcs cdv_intel_dp_enc_funcs = { | ||
1747 | .destroy = cdv_intel_dp_encoder_destroy, | ||
1748 | }; | ||
1749 | |||
1750 | |||
1751 | static void cdv_intel_dp_add_properties(struct drm_connector *connector) | ||
1752 | { | ||
1753 | cdv_intel_attach_force_audio_property(connector); | ||
1754 | cdv_intel_attach_broadcast_rgb_property(connector); | ||
1755 | } | ||
1756 | |||
1757 | /* check the VBT to see whether the eDP is on DP-D port */ | ||
1758 | static bool cdv_intel_dpc_is_edp(struct drm_device *dev) | ||
1759 | { | ||
1760 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
1761 | struct child_device_config *p_child; | ||
1762 | int i; | ||
1763 | |||
1764 | if (!dev_priv->child_dev_num) | ||
1765 | return false; | ||
1766 | |||
1767 | for (i = 0; i < dev_priv->child_dev_num; i++) { | ||
1768 | p_child = dev_priv->child_dev + i; | ||
1769 | |||
1770 | if (p_child->dvo_port == PORT_IDPC && | ||
1771 | p_child->device_type == DEVICE_TYPE_eDP) | ||
1772 | return true; | ||
1773 | } | ||
1774 | return false; | ||
1775 | } | ||
1776 | |||
1777 | /* Cedarview display clock gating | ||
1778 | |||
1779 | We need this disable dot get correct behaviour while enabling | ||
1780 | DP/eDP. TODO - investigate if we can turn it back to normality | ||
1781 | after enabling */ | ||
1782 | static void cdv_disable_intel_clock_gating(struct drm_device *dev) | ||
1783 | { | ||
1784 | u32 reg_value; | ||
1785 | reg_value = REG_READ(DSPCLK_GATE_D); | ||
1786 | |||
1787 | reg_value |= (DPUNIT_PIPEB_GATE_DISABLE | | ||
1788 | DPUNIT_PIPEA_GATE_DISABLE | | ||
1789 | DPCUNIT_CLOCK_GATE_DISABLE | | ||
1790 | DPLSUNIT_CLOCK_GATE_DISABLE | | ||
1791 | DPOUNIT_CLOCK_GATE_DISABLE | | ||
1792 | DPIOUNIT_CLOCK_GATE_DISABLE); | ||
1793 | |||
1794 | REG_WRITE(DSPCLK_GATE_D, reg_value); | ||
1795 | |||
1796 | udelay(500); | ||
1797 | } | ||
1798 | |||
1799 | void | ||
1800 | cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int output_reg) | ||
1801 | { | ||
1802 | struct psb_intel_encoder *psb_intel_encoder; | ||
1803 | struct psb_intel_connector *psb_intel_connector; | ||
1804 | struct drm_connector *connector; | ||
1805 | struct drm_encoder *encoder; | ||
1806 | struct cdv_intel_dp *intel_dp; | ||
1807 | const char *name = NULL; | ||
1808 | int type = DRM_MODE_CONNECTOR_DisplayPort; | ||
1809 | |||
1810 | psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL); | ||
1811 | if (!psb_intel_encoder) | ||
1812 | return; | ||
1813 | psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL); | ||
1814 | if (!psb_intel_connector) | ||
1815 | goto err_connector; | ||
1816 | intel_dp = kzalloc(sizeof(struct cdv_intel_dp), GFP_KERNEL); | ||
1817 | if (!intel_dp) | ||
1818 | goto err_priv; | ||
1819 | |||
1820 | if ((output_reg == DP_C) && cdv_intel_dpc_is_edp(dev)) | ||
1821 | type = DRM_MODE_CONNECTOR_eDP; | ||
1822 | |||
1823 | connector = &psb_intel_connector->base; | ||
1824 | encoder = &psb_intel_encoder->base; | ||
1825 | |||
1826 | drm_connector_init(dev, connector, &cdv_intel_dp_connector_funcs, type); | ||
1827 | drm_encoder_init(dev, encoder, &cdv_intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS); | ||
1828 | |||
1829 | psb_intel_connector_attach_encoder(psb_intel_connector, psb_intel_encoder); | ||
1830 | |||
1831 | if (type == DRM_MODE_CONNECTOR_DisplayPort) | ||
1832 | psb_intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; | ||
1833 | else | ||
1834 | psb_intel_encoder->type = INTEL_OUTPUT_EDP; | ||
1835 | |||
1836 | |||
1837 | psb_intel_encoder->dev_priv=intel_dp; | ||
1838 | intel_dp->encoder = psb_intel_encoder; | ||
1839 | intel_dp->output_reg = output_reg; | ||
1840 | |||
1841 | drm_encoder_helper_add(encoder, &cdv_intel_dp_helper_funcs); | ||
1842 | drm_connector_helper_add(connector, &cdv_intel_dp_connector_helper_funcs); | ||
1843 | |||
1844 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
1845 | connector->interlace_allowed = false; | ||
1846 | connector->doublescan_allowed = false; | ||
1847 | |||
1848 | drm_sysfs_connector_add(connector); | ||
1849 | |||
1850 | /* Set up the DDC bus. */ | ||
1851 | switch (output_reg) { | ||
1852 | case DP_B: | ||
1853 | name = "DPDDC-B"; | ||
1854 | psb_intel_encoder->ddi_select = (DP_MASK | DDI0_SELECT); | ||
1855 | break; | ||
1856 | case DP_C: | ||
1857 | name = "DPDDC-C"; | ||
1858 | psb_intel_encoder->ddi_select = (DP_MASK | DDI1_SELECT); | ||
1859 | break; | ||
1860 | } | ||
1861 | |||
1862 | cdv_disable_intel_clock_gating(dev); | ||
1863 | |||
1864 | cdv_intel_dp_i2c_init(psb_intel_connector, psb_intel_encoder, name); | ||
1865 | /* FIXME:fail check */ | ||
1866 | cdv_intel_dp_add_properties(connector); | ||
1867 | |||
1868 | if (is_edp(psb_intel_encoder)) { | ||
1869 | int ret; | ||
1870 | struct edp_power_seq cur; | ||
1871 | u32 pp_on, pp_off, pp_div; | ||
1872 | u32 pwm_ctrl; | ||
1873 | |||
1874 | pp_on = REG_READ(PP_CONTROL); | ||
1875 | pp_on &= ~PANEL_UNLOCK_MASK; | ||
1876 | pp_on |= PANEL_UNLOCK_REGS; | ||
1877 | |||
1878 | REG_WRITE(PP_CONTROL, pp_on); | ||
1879 | |||
1880 | pwm_ctrl = REG_READ(BLC_PWM_CTL2); | ||
1881 | pwm_ctrl |= PWM_PIPE_B; | ||
1882 | REG_WRITE(BLC_PWM_CTL2, pwm_ctrl); | ||
1883 | |||
1884 | pp_on = REG_READ(PP_ON_DELAYS); | ||
1885 | pp_off = REG_READ(PP_OFF_DELAYS); | ||
1886 | pp_div = REG_READ(PP_DIVISOR); | ||
1887 | |||
1888 | /* Pull timing values out of registers */ | ||
1889 | cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >> | ||
1890 | PANEL_POWER_UP_DELAY_SHIFT; | ||
1891 | |||
1892 | cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >> | ||
1893 | PANEL_LIGHT_ON_DELAY_SHIFT; | ||
1894 | |||
1895 | cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >> | ||
1896 | PANEL_LIGHT_OFF_DELAY_SHIFT; | ||
1897 | |||
1898 | cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >> | ||
1899 | PANEL_POWER_DOWN_DELAY_SHIFT; | ||
1900 | |||
1901 | cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >> | ||
1902 | PANEL_POWER_CYCLE_DELAY_SHIFT); | ||
1903 | |||
1904 | DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", | ||
1905 | cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12); | ||
1906 | |||
1907 | |||
1908 | intel_dp->panel_power_up_delay = cur.t1_t3 / 10; | ||
1909 | intel_dp->backlight_on_delay = cur.t8 / 10; | ||
1910 | intel_dp->backlight_off_delay = cur.t9 / 10; | ||
1911 | intel_dp->panel_power_down_delay = cur.t10 / 10; | ||
1912 | intel_dp->panel_power_cycle_delay = (cur.t11_t12 - 1) * 100; | ||
1913 | |||
1914 | DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n", | ||
1915 | intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay, | ||
1916 | intel_dp->panel_power_cycle_delay); | ||
1917 | |||
1918 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", | ||
1919 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); | ||
1920 | |||
1921 | |||
1922 | cdv_intel_edp_panel_vdd_on(psb_intel_encoder); | ||
1923 | ret = cdv_intel_dp_aux_native_read(psb_intel_encoder, DP_DPCD_REV, | ||
1924 | intel_dp->dpcd, | ||
1925 | sizeof(intel_dp->dpcd)); | ||
1926 | cdv_intel_edp_panel_vdd_off(psb_intel_encoder); | ||
1927 | if (ret == 0) { | ||
1928 | /* if this fails, presume the device is a ghost */ | ||
1929 | DRM_INFO("failed to retrieve link info, disabling eDP\n"); | ||
1930 | cdv_intel_dp_encoder_destroy(encoder); | ||
1931 | cdv_intel_dp_destroy(connector); | ||
1932 | goto err_priv; | ||
1933 | } else { | ||
1934 | DRM_DEBUG_KMS("DPCD: Rev=%x LN_Rate=%x LN_CNT=%x LN_DOWNSP=%x\n", | ||
1935 | intel_dp->dpcd[0], intel_dp->dpcd[1], | ||
1936 | intel_dp->dpcd[2], intel_dp->dpcd[3]); | ||
1937 | |||
1938 | } | ||
1939 | /* The CDV reference driver moves pnale backlight setup into the displays that | ||
1940 | have a backlight: this is a good idea and one we should probably adopt, however | ||
1941 | we need to migrate all the drivers before we can do that */ | ||
1942 | /*cdv_intel_panel_setup_backlight(dev); */ | ||
1943 | } | ||
1944 | return; | ||
1945 | |||
1946 | err_priv: | ||
1947 | kfree(psb_intel_connector); | ||
1948 | err_connector: | ||
1949 | kfree(psb_intel_encoder); | ||
1950 | } | ||
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index a86f87b9ddde..7272a461edfe 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c | |||
@@ -139,8 +139,6 @@ static enum drm_connector_status cdv_hdmi_detect( | |||
139 | { | 139 | { |
140 | struct psb_intel_encoder *psb_intel_encoder = | 140 | struct psb_intel_encoder *psb_intel_encoder = |
141 | psb_intel_attached_encoder(connector); | 141 | psb_intel_attached_encoder(connector); |
142 | struct psb_intel_connector *psb_intel_connector = | ||
143 | to_psb_intel_connector(connector); | ||
144 | struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; | 142 | struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; |
145 | struct edid *edid = NULL; | 143 | struct edid *edid = NULL; |
146 | enum drm_connector_status status = connector_status_disconnected; | 144 | enum drm_connector_status status = connector_status_disconnected; |
@@ -157,8 +155,6 @@ static enum drm_connector_status cdv_hdmi_detect( | |||
157 | hdmi_priv->has_hdmi_audio = | 155 | hdmi_priv->has_hdmi_audio = |
158 | drm_detect_monitor_audio(edid); | 156 | drm_detect_monitor_audio(edid); |
159 | } | 157 | } |
160 | |||
161 | psb_intel_connector->base.display_info.raw_edid = NULL; | ||
162 | kfree(edid); | 158 | kfree(edid); |
163 | } | 159 | } |
164 | return status; | 160 | return status; |
@@ -352,9 +348,11 @@ void cdv_hdmi_init(struct drm_device *dev, | |||
352 | switch (reg) { | 348 | switch (reg) { |
353 | case SDVOB: | 349 | case SDVOB: |
354 | ddc_bus = GPIOE; | 350 | ddc_bus = GPIOE; |
351 | psb_intel_encoder->ddi_select = DDI0_SELECT; | ||
355 | break; | 352 | break; |
356 | case SDVOC: | 353 | case SDVOC: |
357 | ddc_bus = GPIOD; | 354 | ddc_bus = GPIOD; |
355 | psb_intel_encoder->ddi_select = DDI1_SELECT; | ||
358 | break; | 356 | break; |
359 | default: | 357 | default: |
360 | DRM_ERROR("unknown reg 0x%x for HDMI\n", reg); | 358 | DRM_ERROR("unknown reg 0x%x for HDMI\n", reg); |
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 5732b5702e1c..884ba73ac6ce 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c | |||
@@ -764,6 +764,13 @@ static void psb_setup_outputs(struct drm_device *dev) | |||
764 | crtc_mask = dev_priv->ops->hdmi_mask; | 764 | crtc_mask = dev_priv->ops->hdmi_mask; |
765 | clone_mask = (1 << INTEL_OUTPUT_HDMI); | 765 | clone_mask = (1 << INTEL_OUTPUT_HDMI); |
766 | break; | 766 | break; |
767 | case INTEL_OUTPUT_DISPLAYPORT: | ||
768 | crtc_mask = (1 << 0) | (1 << 1); | ||
769 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); | ||
770 | break; | ||
771 | case INTEL_OUTPUT_EDP: | ||
772 | crtc_mask = (1 << 1); | ||
773 | clone_mask = (1 << INTEL_OUTPUT_EDP); | ||
767 | } | 774 | } |
768 | encoder->possible_crtcs = crtc_mask; | 775 | encoder->possible_crtcs = crtc_mask; |
769 | encoder->possible_clones = | 776 | encoder->possible_clones = |
diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index f3a1ae8eb77b..eefd6cc5b80d 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c | |||
@@ -36,7 +36,12 @@ int psb_gem_init_object(struct drm_gem_object *obj) | |||
36 | void psb_gem_free_object(struct drm_gem_object *obj) | 36 | void psb_gem_free_object(struct drm_gem_object *obj) |
37 | { | 37 | { |
38 | struct gtt_range *gtt = container_of(obj, struct gtt_range, gem); | 38 | struct gtt_range *gtt = container_of(obj, struct gtt_range, gem); |
39 | drm_gem_object_release_wrap(obj); | 39 | |
40 | /* Remove the list map if one is present */ | ||
41 | if (obj->map_list.map) | ||
42 | drm_gem_free_mmap_offset(obj); | ||
43 | drm_gem_object_release(obj); | ||
44 | |||
40 | /* This must occur last as it frees up the memory of the GEM object */ | 45 | /* This must occur last as it frees up the memory of the GEM object */ |
41 | psb_gtt_free_range(obj->dev, gtt); | 46 | psb_gtt_free_range(obj->dev, gtt); |
42 | } | 47 | } |
@@ -77,7 +82,7 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, | |||
77 | 82 | ||
78 | /* Make it mmapable */ | 83 | /* Make it mmapable */ |
79 | if (!obj->map_list.map) { | 84 | if (!obj->map_list.map) { |
80 | ret = gem_create_mmap_offset(obj); | 85 | ret = drm_gem_create_mmap_offset(obj); |
81 | if (ret) | 86 | if (ret) |
82 | goto out; | 87 | goto out; |
83 | } | 88 | } |
diff --git a/drivers/gpu/drm/gma500/gem_glue.c b/drivers/gpu/drm/gma500/gem_glue.c deleted file mode 100644 index 3c17634f6061..000000000000 --- a/drivers/gpu/drm/gma500/gem_glue.c +++ /dev/null | |||
@@ -1,90 +0,0 @@ | |||
1 | /************************************************************************** | ||
2 | * Copyright (c) 2011, Intel Corporation. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | **************************************************************************/ | ||
19 | |||
20 | #include <drm/drmP.h> | ||
21 | #include <drm/drm.h> | ||
22 | #include "gem_glue.h" | ||
23 | |||
24 | void drm_gem_object_release_wrap(struct drm_gem_object *obj) | ||
25 | { | ||
26 | /* Remove the list map if one is present */ | ||
27 | if (obj->map_list.map) { | ||
28 | struct drm_gem_mm *mm = obj->dev->mm_private; | ||
29 | struct drm_map_list *list = &obj->map_list; | ||
30 | drm_ht_remove_item(&mm->offset_hash, &list->hash); | ||
31 | drm_mm_put_block(list->file_offset_node); | ||
32 | kfree(list->map); | ||
33 | list->map = NULL; | ||
34 | } | ||
35 | drm_gem_object_release(obj); | ||
36 | } | ||
37 | |||
38 | /** | ||
39 | * gem_create_mmap_offset - invent an mmap offset | ||
40 | * @obj: our object | ||
41 | * | ||
42 | * Standard implementation of offset generation for mmap as is | ||
43 | * duplicated in several drivers. This belongs in GEM. | ||
44 | */ | ||
45 | int gem_create_mmap_offset(struct drm_gem_object *obj) | ||
46 | { | ||
47 | struct drm_device *dev = obj->dev; | ||
48 | struct drm_gem_mm *mm = dev->mm_private; | ||
49 | struct drm_map_list *list; | ||
50 | struct drm_local_map *map; | ||
51 | int ret; | ||
52 | |||
53 | list = &obj->map_list; | ||
54 | list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); | ||
55 | if (list->map == NULL) | ||
56 | return -ENOMEM; | ||
57 | map = list->map; | ||
58 | map->type = _DRM_GEM; | ||
59 | map->size = obj->size; | ||
60 | map->handle = obj; | ||
61 | |||
62 | list->file_offset_node = drm_mm_search_free(&mm->offset_manager, | ||
63 | obj->size / PAGE_SIZE, 0, 0); | ||
64 | if (!list->file_offset_node) { | ||
65 | dev_err(dev->dev, "failed to allocate offset for bo %d\n", | ||
66 | obj->name); | ||
67 | ret = -ENOSPC; | ||
68 | goto free_it; | ||
69 | } | ||
70 | list->file_offset_node = drm_mm_get_block(list->file_offset_node, | ||
71 | obj->size / PAGE_SIZE, 0); | ||
72 | if (!list->file_offset_node) { | ||
73 | ret = -ENOMEM; | ||
74 | goto free_it; | ||
75 | } | ||
76 | list->hash.key = list->file_offset_node->start; | ||
77 | ret = drm_ht_insert_item(&mm->offset_hash, &list->hash); | ||
78 | if (ret) { | ||
79 | dev_err(dev->dev, "failed to add to map hash\n"); | ||
80 | goto free_mm; | ||
81 | } | ||
82 | return 0; | ||
83 | |||
84 | free_mm: | ||
85 | drm_mm_put_block(list->file_offset_node); | ||
86 | free_it: | ||
87 | kfree(list->map); | ||
88 | list->map = NULL; | ||
89 | return ret; | ||
90 | } | ||
diff --git a/drivers/gpu/drm/gma500/gem_glue.h b/drivers/gpu/drm/gma500/gem_glue.h deleted file mode 100644 index ce5ce30f74db..000000000000 --- a/drivers/gpu/drm/gma500/gem_glue.h +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | extern void drm_gem_object_release_wrap(struct drm_gem_object *obj); | ||
2 | extern int gem_create_mmap_offset(struct drm_gem_object *obj); | ||
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c index a837ee97787c..403fffb03abd 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 | ||
57 | static void | ||
58 | parse_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 | |||
57 | static u16 | 149 | static u16 |
58 | get_blocksize(void *p) | 150 | get_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 | ||
27 | struct vbt_header { | 28 | struct 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 | |||
394 | struct bdb_driver_features { | 401 | struct 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 | |||
458 | struct edp_power_seq { | ||
459 | u16 t1_t3; | ||
460 | u16 t8; | ||
461 | u16 t9; | ||
462 | u16 t10; | ||
463 | u16 t11_t12; | ||
464 | } __attribute__ ((packed)); | ||
465 | |||
466 | struct edp_link_params { | ||
467 | u8 rate:4; | ||
468 | u8 lanes:4; | ||
469 | u8 preemphasis:4; | ||
470 | u8 vswing:4; | ||
471 | } __attribute__ ((packed)); | ||
472 | |||
473 | struct 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 | |||
434 | extern int psb_intel_init_bios(struct drm_device *dev); | 480 | extern int psb_intel_init_bios(struct drm_device *dev); |
435 | extern void psb_intel_destroy_bios(struct drm_device *dev); | 481 | extern 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 | } |
314 | set_prop_done: | 305 | set_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 64d18a37da40..a97e38e284fa 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 | ||
121 | struct vbt_header { | 121 | struct 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 */ |
127 | struct vbt_r0 { | 127 | struct 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 | ||
133 | struct vbt_r10 { | 133 | struct 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/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c index 2eb3dc4e9c9b..69e51e903f35 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c | |||
@@ -252,7 +252,6 @@ static int oaktrail_hdmi_get_modes(struct drm_connector *connector) | |||
252 | if (edid) { | 252 | if (edid) { |
253 | drm_mode_connector_update_edid_property(connector, edid); | 253 | drm_mode_connector_update_edid_property(connector, edid); |
254 | ret = drm_add_edid_modes(connector, edid); | 254 | ret = drm_add_edid_modes(connector, edid); |
255 | connector->display_info.raw_edid = NULL; | ||
256 | } | 255 | } |
257 | 256 | ||
258 | /* | 257 | /* |
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_device.c b/drivers/gpu/drm/gma500/psb_device.c index 7563cd51851a..b58c4701c4e8 100644 --- a/drivers/gpu/drm/gma500/psb_device.c +++ b/drivers/gpu/drm/gma500/psb_device.c | |||
@@ -290,6 +290,7 @@ static void psb_get_core_freq(struct drm_device *dev) | |||
290 | case 6: | 290 | case 6: |
291 | case 7: | 291 | case 7: |
292 | dev_priv->core_freq = 266; | 292 | dev_priv->core_freq = 266; |
293 | break; | ||
293 | default: | 294 | default: |
294 | dev_priv->core_freq = 0; | 295 | dev_priv->core_freq = 0; |
295 | } | 296 | } |
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index b15282fdbf97..a7fd6c48b793 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h | |||
@@ -24,10 +24,10 @@ | |||
24 | 24 | ||
25 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
26 | #include <drm/drm_global.h> | 26 | #include <drm/drm_global.h> |
27 | #include "gem_glue.h" | ||
28 | #include <drm/gma_drm.h> | 27 | #include <drm/gma_drm.h> |
29 | #include "psb_reg.h" | 28 | #include "psb_reg.h" |
30 | #include "psb_intel_drv.h" | 29 | #include "psb_intel_drv.h" |
30 | #include "intel_bios.h" | ||
31 | #include "gtt.h" | 31 | #include "gtt.h" |
32 | #include "power.h" | 32 | #include "power.h" |
33 | #include "opregion.h" | 33 | #include "opregion.h" |
@@ -613,6 +613,8 @@ struct drm_psb_private { | |||
613 | */ | 613 | */ |
614 | struct backlight_device *backlight_device; | 614 | struct backlight_device *backlight_device; |
615 | struct drm_property *backlight_property; | 615 | struct drm_property *backlight_property; |
616 | bool backlight_enabled; | ||
617 | int backlight_level; | ||
616 | uint32_t blc_adj1; | 618 | uint32_t blc_adj1; |
617 | uint32_t blc_adj2; | 619 | uint32_t blc_adj2; |
618 | 620 | ||
@@ -640,6 +642,19 @@ struct drm_psb_private { | |||
640 | int mdfld_panel_id; | 642 | int mdfld_panel_id; |
641 | 643 | ||
642 | bool dplla_96mhz; /* DPLL data from the VBT */ | 644 | bool dplla_96mhz; /* DPLL data from the VBT */ |
645 | |||
646 | struct { | ||
647 | int rate; | ||
648 | int lanes; | ||
649 | int preemphasis; | ||
650 | int vswing; | ||
651 | |||
652 | bool initialized; | ||
653 | bool support; | ||
654 | int bpp; | ||
655 | struct edp_power_seq pps; | ||
656 | } edp; | ||
657 | uint8_t panel_type; | ||
643 | }; | 658 | }; |
644 | 659 | ||
645 | 660 | ||
@@ -796,6 +811,9 @@ extern int psb_fbdev_init(struct drm_device *dev); | |||
796 | /* backlight.c */ | 811 | /* backlight.c */ |
797 | int gma_backlight_init(struct drm_device *dev); | 812 | int gma_backlight_init(struct drm_device *dev); |
798 | void gma_backlight_exit(struct drm_device *dev); | 813 | void gma_backlight_exit(struct drm_device *dev); |
814 | void gma_backlight_disable(struct drm_device *dev); | ||
815 | void gma_backlight_enable(struct drm_device *dev); | ||
816 | void gma_backlight_set(struct drm_device *dev, int v); | ||
799 | 817 | ||
800 | /* oaktrail_crtc.c */ | 818 | /* oaktrail_crtc.c */ |
801 | extern const struct drm_crtc_helper_funcs oaktrail_helper_funcs; | 819 | extern const struct drm_crtc_helper_funcs oaktrail_helper_funcs; |
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h index ebe1a28f60e1..90f2d11e686b 100644 --- a/drivers/gpu/drm/gma500/psb_intel_drv.h +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h | |||
@@ -29,10 +29,6 @@ | |||
29 | * Display related stuff | 29 | * Display related stuff |
30 | */ | 30 | */ |
31 | 31 | ||
32 | /* store information about an Ixxx DVO */ | ||
33 | /* The i830->i865 use multiple DVOs with multiple i2cs */ | ||
34 | /* the i915, i945 have a single sDVO i2c bus - which is different */ | ||
35 | #define MAX_OUTPUTS 6 | ||
36 | /* maximum connectors per crtcs in the mode set */ | 32 | /* maximum connectors per crtcs in the mode set */ |
37 | #define INTELFB_CONN_LIMIT 4 | 33 | #define INTELFB_CONN_LIMIT 4 |
38 | 34 | ||
@@ -69,6 +65,8 @@ | |||
69 | #define INTEL_OUTPUT_HDMI 6 | 65 | #define INTEL_OUTPUT_HDMI 6 |
70 | #define INTEL_OUTPUT_MIPI 7 | 66 | #define INTEL_OUTPUT_MIPI 7 |
71 | #define INTEL_OUTPUT_MIPI2 8 | 67 | #define INTEL_OUTPUT_MIPI2 8 |
68 | #define INTEL_OUTPUT_DISPLAYPORT 9 | ||
69 | #define INTEL_OUTPUT_EDP 10 | ||
72 | 70 | ||
73 | #define INTEL_DVO_CHIP_NONE 0 | 71 | #define INTEL_DVO_CHIP_NONE 0 |
74 | #define INTEL_DVO_CHIP_LVDS 1 | 72 | #define INTEL_DVO_CHIP_LVDS 1 |
@@ -133,6 +131,11 @@ struct psb_intel_encoder { | |||
133 | void (*hot_plug)(struct psb_intel_encoder *); | 131 | void (*hot_plug)(struct psb_intel_encoder *); |
134 | int crtc_mask; | 132 | int crtc_mask; |
135 | int clone_mask; | 133 | int clone_mask; |
134 | u32 ddi_select; /* Channel info */ | ||
135 | #define DDI0_SELECT 0x01 | ||
136 | #define DDI1_SELECT 0x02 | ||
137 | #define DP_MASK 0x8000 | ||
138 | #define DDI_MASK 0x03 | ||
136 | void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */ | 139 | void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */ |
137 | 140 | ||
138 | /* FIXME: Either make SDVO and LVDS store it's i2c here or give CDV it's | 141 | /* FIXME: Either make SDVO and LVDS store it's i2c here or give CDV it's |
@@ -190,7 +193,6 @@ struct psb_intel_crtc { | |||
190 | u32 mode_flags; | 193 | u32 mode_flags; |
191 | 194 | ||
192 | bool active; | 195 | bool active; |
193 | bool crtc_enable; | ||
194 | 196 | ||
195 | /* Saved Crtc HW states */ | 197 | /* Saved Crtc HW states */ |
196 | struct psb_intel_crtc_state *crtc_state; | 198 | struct psb_intel_crtc_state *crtc_state; |
@@ -285,4 +287,20 @@ extern void gma_intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed); | |||
285 | extern void gma_intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit); | 287 | extern void gma_intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit); |
286 | extern void gma_intel_teardown_gmbus(struct drm_device *dev); | 288 | extern void gma_intel_teardown_gmbus(struct drm_device *dev); |
287 | 289 | ||
290 | /* DP support */ | ||
291 | extern void cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, int output_reg); | ||
292 | extern void cdv_intel_dp_set_m_n(struct drm_crtc *crtc, | ||
293 | struct drm_display_mode *mode, | ||
294 | struct drm_display_mode *adjusted_mode); | ||
295 | |||
296 | extern void psb_intel_attach_force_audio_property(struct drm_connector *connector); | ||
297 | extern void psb_intel_attach_broadcast_rgb_property(struct drm_connector *connector); | ||
298 | |||
299 | extern int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val); | ||
300 | extern int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val); | ||
301 | extern void cdv_sb_reset(struct drm_device *dev); | ||
302 | |||
303 | extern void cdv_intel_attach_force_audio_property(struct drm_connector *connector); | ||
304 | extern void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector); | ||
305 | |||
288 | #endif /* __INTEL_DRV_H__ */ | 306 | #endif /* __INTEL_DRV_H__ */ |
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 8e8c8efb0a89..d914719c4b60 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) |
@@ -1282,6 +1313,10 @@ No status bits are changed. | |||
1282 | # define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* Fixed value on CDV */ | 1313 | # define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* Fixed value on CDV */ |
1283 | # define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) | 1314 | # define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) |
1284 | # define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) | 1315 | # define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) |
1316 | # define DPUNIT_PIPEB_GATE_DISABLE (1 << 30) | ||
1317 | # define DPUNIT_PIPEA_GATE_DISABLE (1 << 25) | ||
1318 | # define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) | ||
1319 | # define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) | ||
1285 | 1320 | ||
1286 | #define RAMCLK_GATE_D 0x6210 | 1321 | #define RAMCLK_GATE_D 0x6210 |
1287 | 1322 | ||
@@ -1347,5 +1382,165 @@ No status bits are changed. | |||
1347 | #define LANE_PLL_ENABLE (0x3 << 20) | 1382 | #define LANE_PLL_ENABLE (0x3 << 20) |
1348 | #define LANE_PLL_PIPE(p) (((p) == 0) ? (1 << 21) : (0 << 21)) | 1383 | #define LANE_PLL_PIPE(p) (((p) == 0) ? (1 << 21) : (0 << 21)) |
1349 | 1384 | ||
1385 | #define DP_B 0x64100 | ||
1386 | #define DP_C 0x64200 | ||
1387 | |||
1388 | #define DP_PORT_EN (1 << 31) | ||
1389 | #define DP_PIPEB_SELECT (1 << 30) | ||
1390 | #define DP_PIPE_MASK (1 << 30) | ||
1391 | |||
1392 | /* Link training mode - select a suitable mode for each stage */ | ||
1393 | #define DP_LINK_TRAIN_PAT_1 (0 << 28) | ||
1394 | #define DP_LINK_TRAIN_PAT_2 (1 << 28) | ||
1395 | #define DP_LINK_TRAIN_PAT_IDLE (2 << 28) | ||
1396 | #define DP_LINK_TRAIN_OFF (3 << 28) | ||
1397 | #define DP_LINK_TRAIN_MASK (3 << 28) | ||
1398 | #define DP_LINK_TRAIN_SHIFT 28 | ||
1399 | |||
1400 | /* Signal voltages. These are mostly controlled by the other end */ | ||
1401 | #define DP_VOLTAGE_0_4 (0 << 25) | ||
1402 | #define DP_VOLTAGE_0_6 (1 << 25) | ||
1403 | #define DP_VOLTAGE_0_8 (2 << 25) | ||
1404 | #define DP_VOLTAGE_1_2 (3 << 25) | ||
1405 | #define DP_VOLTAGE_MASK (7 << 25) | ||
1406 | #define DP_VOLTAGE_SHIFT 25 | ||
1407 | |||
1408 | /* Signal pre-emphasis levels, like voltages, the other end tells us what | ||
1409 | * they want | ||
1410 | */ | ||
1411 | #define DP_PRE_EMPHASIS_0 (0 << 22) | ||
1412 | #define DP_PRE_EMPHASIS_3_5 (1 << 22) | ||
1413 | #define DP_PRE_EMPHASIS_6 (2 << 22) | ||
1414 | #define DP_PRE_EMPHASIS_9_5 (3 << 22) | ||
1415 | #define DP_PRE_EMPHASIS_MASK (7 << 22) | ||
1416 | #define DP_PRE_EMPHASIS_SHIFT 22 | ||
1417 | |||
1418 | /* How many wires to use. I guess 3 was too hard */ | ||
1419 | #define DP_PORT_WIDTH_1 (0 << 19) | ||
1420 | #define DP_PORT_WIDTH_2 (1 << 19) | ||
1421 | #define DP_PORT_WIDTH_4 (3 << 19) | ||
1422 | #define DP_PORT_WIDTH_MASK (7 << 19) | ||
1423 | |||
1424 | /* Mystic DPCD version 1.1 special mode */ | ||
1425 | #define DP_ENHANCED_FRAMING (1 << 18) | ||
1426 | |||
1427 | /** locked once port is enabled */ | ||
1428 | #define DP_PORT_REVERSAL (1 << 15) | ||
1429 | |||
1430 | /** sends the clock on lane 15 of the PEG for debug */ | ||
1431 | #define DP_CLOCK_OUTPUT_ENABLE (1 << 13) | ||
1432 | |||
1433 | #define DP_SCRAMBLING_DISABLE (1 << 12) | ||
1434 | #define DP_SCRAMBLING_DISABLE_IRONLAKE (1 << 7) | ||
1435 | |||
1436 | /** limit RGB values to avoid confusing TVs */ | ||
1437 | #define DP_COLOR_RANGE_16_235 (1 << 8) | ||
1438 | |||
1439 | /** Turn on the audio link */ | ||
1440 | #define DP_AUDIO_OUTPUT_ENABLE (1 << 6) | ||
1441 | |||
1442 | /** vs and hs sync polarity */ | ||
1443 | #define DP_SYNC_VS_HIGH (1 << 4) | ||
1444 | #define DP_SYNC_HS_HIGH (1 << 3) | ||
1445 | |||
1446 | /** A fantasy */ | ||
1447 | #define DP_DETECTED (1 << 2) | ||
1448 | |||
1449 | /** The aux channel provides a way to talk to the | ||
1450 | * signal sink for DDC etc. Max packet size supported | ||
1451 | * is 20 bytes in each direction, hence the 5 fixed | ||
1452 | * data registers | ||
1453 | */ | ||
1454 | #define DPB_AUX_CH_CTL 0x64110 | ||
1455 | #define DPB_AUX_CH_DATA1 0x64114 | ||
1456 | #define DPB_AUX_CH_DATA2 0x64118 | ||
1457 | #define DPB_AUX_CH_DATA3 0x6411c | ||
1458 | #define DPB_AUX_CH_DATA4 0x64120 | ||
1459 | #define DPB_AUX_CH_DATA5 0x64124 | ||
1460 | |||
1461 | #define DPC_AUX_CH_CTL 0x64210 | ||
1462 | #define DPC_AUX_CH_DATA1 0x64214 | ||
1463 | #define DPC_AUX_CH_DATA2 0x64218 | ||
1464 | #define DPC_AUX_CH_DATA3 0x6421c | ||
1465 | #define DPC_AUX_CH_DATA4 0x64220 | ||
1466 | #define DPC_AUX_CH_DATA5 0x64224 | ||
1467 | |||
1468 | #define DP_AUX_CH_CTL_SEND_BUSY (1 << 31) | ||
1469 | #define DP_AUX_CH_CTL_DONE (1 << 30) | ||
1470 | #define DP_AUX_CH_CTL_INTERRUPT (1 << 29) | ||
1471 | #define DP_AUX_CH_CTL_TIME_OUT_ERROR (1 << 28) | ||
1472 | #define DP_AUX_CH_CTL_TIME_OUT_400us (0 << 26) | ||
1473 | #define DP_AUX_CH_CTL_TIME_OUT_600us (1 << 26) | ||
1474 | #define DP_AUX_CH_CTL_TIME_OUT_800us (2 << 26) | ||
1475 | #define DP_AUX_CH_CTL_TIME_OUT_1600us (3 << 26) | ||
1476 | #define DP_AUX_CH_CTL_TIME_OUT_MASK (3 << 26) | ||
1477 | #define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25) | ||
1478 | #define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20) | ||
1479 | #define DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT 20 | ||
1480 | #define DP_AUX_CH_CTL_PRECHARGE_2US_MASK (0xf << 16) | ||
1481 | #define DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT 16 | ||
1482 | #define DP_AUX_CH_CTL_AUX_AKSV_SELECT (1 << 15) | ||
1483 | #define DP_AUX_CH_CTL_MANCHESTER_TEST (1 << 14) | ||
1484 | #define DP_AUX_CH_CTL_SYNC_TEST (1 << 13) | ||
1485 | #define DP_AUX_CH_CTL_DEGLITCH_TEST (1 << 12) | ||
1486 | #define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11) | ||
1487 | #define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff) | ||
1488 | #define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0 | ||
1489 | |||
1490 | /* | ||
1491 | * Computing GMCH M and N values for the Display Port link | ||
1492 | * | ||
1493 | * GMCH M/N = dot clock * bytes per pixel / ls_clk * # of lanes | ||
1494 | * | ||
1495 | * ls_clk (we assume) is the DP link clock (1.62 or 2.7 GHz) | ||
1496 | * | ||
1497 | * The GMCH value is used internally | ||
1498 | * | ||
1499 | * bytes_per_pixel is the number of bytes coming out of the plane, | ||
1500 | * which is after the LUTs, so we want the bytes for our color format. | ||
1501 | * For our current usage, this is always 3, one byte for R, G and B. | ||
1502 | */ | ||
1503 | |||
1504 | #define _PIPEA_GMCH_DATA_M 0x70050 | ||
1505 | #define _PIPEB_GMCH_DATA_M 0x71050 | ||
1506 | |||
1507 | /* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */ | ||
1508 | #define PIPE_GMCH_DATA_M_TU_SIZE_MASK (0x3f << 25) | ||
1509 | #define PIPE_GMCH_DATA_M_TU_SIZE_SHIFT 25 | ||
1510 | |||
1511 | #define PIPE_GMCH_DATA_M_MASK (0xffffff) | ||
1512 | |||
1513 | #define _PIPEA_GMCH_DATA_N 0x70054 | ||
1514 | #define _PIPEB_GMCH_DATA_N 0x71054 | ||
1515 | #define PIPE_GMCH_DATA_N_MASK (0xffffff) | ||
1516 | |||
1517 | /* | ||
1518 | * Computing Link M and N values for the Display Port link | ||
1519 | * | ||
1520 | * Link M / N = pixel_clock / ls_clk | ||
1521 | * | ||
1522 | * (the DP spec calls pixel_clock the 'strm_clk') | ||
1523 | * | ||
1524 | * The Link value is transmitted in the Main Stream | ||
1525 | * Attributes and VB-ID. | ||
1526 | */ | ||
1527 | |||
1528 | #define _PIPEA_DP_LINK_M 0x70060 | ||
1529 | #define _PIPEB_DP_LINK_M 0x71060 | ||
1530 | #define PIPEA_DP_LINK_M_MASK (0xffffff) | ||
1531 | |||
1532 | #define _PIPEA_DP_LINK_N 0x70064 | ||
1533 | #define _PIPEB_DP_LINK_N 0x71064 | ||
1534 | #define PIPEA_DP_LINK_N_MASK (0xffffff) | ||
1535 | |||
1536 | #define PIPE_GMCH_DATA_M(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_M, _PIPEB_GMCH_DATA_M) | ||
1537 | #define PIPE_GMCH_DATA_N(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_N, _PIPEB_GMCH_DATA_N) | ||
1538 | #define PIPE_DP_LINK_M(pipe) _PIPE(pipe, _PIPEA_DP_LINK_M, _PIPEB_DP_LINK_M) | ||
1539 | #define PIPE_DP_LINK_N(pipe) _PIPE(pipe, _PIPEA_DP_LINK_N, _PIPEB_DP_LINK_N) | ||
1540 | |||
1541 | #define PIPE_BPC_MASK (7 << 5) | ||
1542 | #define PIPE_8BPC (0 << 5) | ||
1543 | #define PIPE_10BPC (1 << 5) | ||
1544 | #define PIPE_6BPC (2 << 5) | ||
1350 | 1545 | ||
1351 | #endif | 1546 | #endif |
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index c148d92229fd..fc9292705dbf 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c | |||
@@ -1291,7 +1291,6 @@ psb_intel_sdvo_get_analog_edid(struct drm_connector *connector) | |||
1291 | 1291 | ||
1292 | return drm_get_edid(connector, | 1292 | return drm_get_edid(connector, |
1293 | &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); | 1293 | &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); |
1294 | return NULL; | ||
1295 | } | 1294 | } |
1296 | 1295 | ||
1297 | static enum drm_connector_status | 1296 | static enum drm_connector_status |
@@ -1342,7 +1341,6 @@ psb_intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1342 | } | 1341 | } |
1343 | } else | 1342 | } else |
1344 | status = connector_status_disconnected; | 1343 | status = connector_status_disconnected; |
1345 | connector->display_info.raw_edid = NULL; | ||
1346 | kfree(edid); | 1344 | kfree(edid); |
1347 | } | 1345 | } |
1348 | 1346 | ||
@@ -1403,7 +1401,6 @@ psb_intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1403 | ret = connector_status_disconnected; | 1401 | ret = connector_status_disconnected; |
1404 | else | 1402 | else |
1405 | ret = connector_status_connected; | 1403 | ret = connector_status_connected; |
1406 | connector->display_info.raw_edid = NULL; | ||
1407 | kfree(edid); | 1404 | kfree(edid); |
1408 | } else | 1405 | } else |
1409 | ret = connector_status_connected; | 1406 | ret = connector_status_connected; |
@@ -1452,7 +1449,6 @@ static void psb_intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1452 | drm_add_edid_modes(connector, edid); | 1449 | drm_add_edid_modes(connector, edid); |
1453 | } | 1450 | } |
1454 | 1451 | ||
1455 | connector->display_info.raw_edid = NULL; | ||
1456 | kfree(edid); | 1452 | kfree(edid); |
1457 | } | 1453 | } |
1458 | } | 1454 | } |