aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/gma500
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-08-08 09:54:41 -0400
committerDave Airlie <airlied@redhat.com>2012-08-23 19:29:12 -0400
commit220801bdb53ceeac01d021ac459d112acc7deb0b (patch)
tree87c64cbd330b26754922caca5c94c67082e8de0d /drivers/gpu/drm/gma500
parent8695b612943561478fd22f28f45e5692e5d078db (diff)
gma500/cdv: add the bits that don't need the new code
Based on bits from Yakui <yakui.zhao@intel.com> We can import various little bits of code before we plumb it all in and hopefully this way catch any regressions more easily. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/gma500')
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c59
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_display.c99
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c4
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_drv.h2
4 files changed, 161 insertions, 3 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index b7e7b49d8f62..e2fff244a599 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -488,6 +488,65 @@ static void cdv_hotplug_enable(struct drm_device *dev, bool on)
488 } 488 }
489} 489}
490 490
491static const char *force_audio_names[] = {
492 "off",
493 "auto",
494 "on",
495};
496
497void cdv_intel_attach_force_audio_property(struct drm_connector *connector)
498{
499 struct drm_device *dev = connector->dev;
500 struct drm_psb_private *dev_priv = dev->dev_private;
501 struct drm_property *prop;
502 int i;
503
504 prop = dev_priv->force_audio_property;
505 if (prop == NULL) {
506 prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
507 "audio",
508 ARRAY_SIZE(force_audio_names));
509 if (prop == NULL)
510 return;
511
512 for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
513 drm_property_add_enum(prop, i, i-1, force_audio_names[i]);
514
515 dev_priv->force_audio_property = prop;
516 }
517 drm_connector_attach_property(connector, prop, 0);
518}
519
520
521static const char *broadcast_rgb_names[] = {
522 "Full",
523 "Limited 16:235",
524};
525
526void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector)
527{
528 struct drm_device *dev = connector->dev;
529 struct drm_psb_private *dev_priv = dev->dev_private;
530 struct drm_property *prop;
531 int i;
532
533 prop = dev_priv->broadcast_rgb_property;
534 if (prop == NULL) {
535 prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
536 "Broadcast RGB",
537 ARRAY_SIZE(broadcast_rgb_names));
538 if (prop == NULL)
539 return;
540
541 for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++)
542 drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]);
543
544 dev_priv->broadcast_rgb_property = prop;
545 }
546
547 drm_connector_attach_property(connector, prop, 0);
548}
549
491/* Cedarview */ 550/* Cedarview */
492static const struct psb_offset cdv_regmap[2] = { 551static const struct psb_offset cdv_regmap[2] = {
493 { 552 {
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c
index f16169c95dec..2e0231e909ff 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_display.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
@@ -64,11 +64,16 @@ struct cdv_intel_limit_t {
64static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit, 64static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit,
65 struct drm_crtc *crtc, int target, int refclk, 65 struct drm_crtc *crtc, int target, int refclk,
66 struct cdv_intel_clock_t *best_clock); 66 struct cdv_intel_clock_t *best_clock);
67static 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);
67 70
68#define CDV_LIMIT_SINGLE_LVDS_96 0 71#define CDV_LIMIT_SINGLE_LVDS_96 0
69#define CDV_LIMIT_SINGLE_LVDS_100 1 72#define CDV_LIMIT_SINGLE_LVDS_100 1
70#define CDV_LIMIT_DAC_HDMI_27 2 73#define CDV_LIMIT_DAC_HDMI_27 2
71#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
72 77
73static const struct cdv_intel_limit_t cdv_intel_limits[] = { 78static const struct cdv_intel_limit_t cdv_intel_limits[] = {
74 { /* CDV_SIGNLE_LVDS_96MHz */ 79 { /* CDV_SIGNLE_LVDS_96MHz */
@@ -123,6 +128,30 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
123 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5}, 128 .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
124 .find_pll = cdv_intel_find_best_PLL, 129 .find_pll = cdv_intel_find_best_PLL,
125 }, 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,
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 }
126}; 155};
127 156
128#define _wait_for(COND, MS, W) ({ \ 157#define _wait_for(COND, MS, W) ({ \
@@ -269,7 +298,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
269 ref_value &= ~(REF_CLK_MASK); 298 ref_value &= ~(REF_CLK_MASK);
270 299
271 /* use DPLL_A for pipeB on CRT/HDMI */ 300 /* use DPLL_A for pipeB on CRT/HDMI */
272 if (pipe == 1 && !is_lvds) { 301 if (pipe == 1 && !is_lvds && !(ddi_select & DP_MASK)) {
273 DRM_DEBUG_KMS("use DPLLA for pipe B\n"); 302 DRM_DEBUG_KMS("use DPLLA for pipe B\n");
274 ref_value |= REF_CLK_DPLLA; 303 ref_value |= REF_CLK_DPLLA;
275 } else { 304 } else {
@@ -409,6 +438,11 @@ static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
409 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96]; 438 limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
410 else 439 else
411 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 if (refclk == 27000)
443 limit = &cdv_intel_limits[CDV_LIMIT_DP_27];
444 else
445 limit = &cdv_intel_limits[CDV_LIMIT_DP_100];
412 } else { 446 } else {
413 if (refclk == 27000) 447 if (refclk == 27000)
414 limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27]; 448 limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27];
@@ -510,6 +544,49 @@ static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit,
510 return err != target; 544 return err != target;
511} 545}
512 546
547static bool cdv_intel_find_dp_pll(const struct cdv_intel_limit_t *limit, struct drm_crtc *crtc, int target,
548 int refclk,
549 struct cdv_intel_clock_t *best_clock)
550{
551 struct cdv_intel_clock_t clock;
552 if (refclk == 27000) {
553 if (target < 200000) {
554 clock.p1 = 2;
555 clock.p2 = 10;
556 clock.n = 1;
557 clock.m1 = 0;
558 clock.m2 = 118;
559 } else {
560 clock.p1 = 1;
561 clock.p2 = 10;
562 clock.n = 1;
563 clock.m1 = 0;
564 clock.m2 = 98;
565 }
566 } else if (refclk == 100000) {
567 if (target < 200000) {
568 clock.p1 = 2;
569 clock.p2 = 10;
570 clock.n = 5;
571 clock.m1 = 0;
572 clock.m2 = 160;
573 } else {
574 clock.p1 = 1;
575 clock.p2 = 10;
576 clock.n = 5;
577 clock.m1 = 0;
578 clock.m2 = 133;
579 }
580 } else
581 return false;
582 clock.m = clock.m2 + 2;
583 clock.p = clock.p1 * clock.p2;
584 clock.vco = (refclk * clock.m) / clock.n;
585 clock.dot = clock.vco / clock.p;
586 memcpy(best_clock, &clock, sizeof(struct cdv_intel_clock_t));
587 return true;
588}
589
513static int cdv_intel_pipe_set_base(struct drm_crtc *crtc, 590static int cdv_intel_pipe_set_base(struct drm_crtc *crtc,
514 int x, int y, struct drm_framebuffer *old_fb) 591 int x, int y, struct drm_framebuffer *old_fb)
515{ 592{
@@ -963,7 +1040,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
963 u32 dpll = 0, dspcntr, pipeconf; 1040 u32 dpll = 0, dspcntr, pipeconf;
964 bool ok; 1041 bool ok;
965 bool is_crt = false, is_lvds = false, is_tv = false; 1042 bool is_crt = false, is_lvds = false, is_tv = false;
966 bool is_hdmi = false; 1043 bool is_hdmi = false, is_dp = false;
967 struct drm_mode_config *mode_config = &dev->mode_config; 1044 struct drm_mode_config *mode_config = &dev->mode_config;
968 struct drm_connector *connector; 1045 struct drm_connector *connector;
969 const struct cdv_intel_limit_t *limit; 1046 const struct cdv_intel_limit_t *limit;
@@ -991,6 +1068,9 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
991 case INTEL_OUTPUT_HDMI: 1068 case INTEL_OUTPUT_HDMI:
992 is_hdmi = true; 1069 is_hdmi = true;
993 break; 1070 break;
1071 case INTEL_OUTPUT_DISPLAYPORT:
1072 is_dp = true;
1073 break;
994 default: 1074 default:
995 DRM_ERROR("invalid output type.\n"); 1075 DRM_ERROR("invalid output type.\n");
996 return 0; 1076 return 0;
@@ -1003,6 +1083,12 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1003 else 1083 else
1004 /* high-end sku, 27/100 mhz */ 1084 /* high-end sku, 27/100 mhz */
1005 refclk = 27000; 1085 refclk = 27000;
1086 if (is_dp) {
1087 if (pipe == 0)
1088 refclk = 27000;
1089 else
1090 refclk = 100000;
1091 }
1006 1092
1007 if (is_lvds && dev_priv->lvds_use_ssc) { 1093 if (is_lvds && dev_priv->lvds_use_ssc) {
1008 refclk = dev_priv->lvds_ssc_freq * 1000; 1094 refclk = dev_priv->lvds_ssc_freq * 1000;
@@ -1028,6 +1114,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
1028 } 1114 }
1029/* dpll |= PLL_REF_INPUT_DREFCLK; */ 1115/* dpll |= PLL_REF_INPUT_DREFCLK; */
1030 1116
1117 if (is_dp) {
1118/*FIXME cdv_intel_dp_set_m_n(crtc, mode, adjusted_mode); */
1119 } else {
1120 REG_WRITE(PIPE_GMCH_DATA_M(pipe), 0);
1121 REG_WRITE(PIPE_GMCH_DATA_N(pipe), 0);
1122 REG_WRITE(PIPE_DP_LINK_M(pipe), 0);
1123 REG_WRITE(PIPE_DP_LINK_N(pipe), 0);
1124 }
1125
1031 dpll |= DPLL_SYNCLOCK_ENABLE; 1126 dpll |= DPLL_SYNCLOCK_ENABLE;
1032/* if (is_lvds) 1127/* if (is_lvds)
1033 dpll |= DPLLB_MODE_LVDS; 1128 dpll |= DPLLB_MODE_LVDS;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 5732b5702e1c..2de6b1fcc135 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -764,6 +764,10 @@ 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;
767 } 771 }
768 encoder->possible_crtcs = crtc_mask; 772 encoder->possible_crtcs = crtc_mask;
769 encoder->possible_clones = 773 encoder->possible_clones =
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index 73214e281fab..c574c0199103 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -134,7 +134,7 @@ struct psb_intel_encoder {
134 u32 ddi_select; /* Channel info */ 134 u32 ddi_select; /* Channel info */
135#define DDI0_SELECT 0x01 135#define DDI0_SELECT 0x01
136#define DDI1_SELECT 0x02 136#define DDI1_SELECT 0x02
137#define DP_MASK 0x8000; 137#define DP_MASK 0x8000
138#define DDI_MASK 0x03 138#define DDI_MASK 0x03
139 void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */ 139 void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */
140 140