From: Alan Cox <alan@lxorguk.ukuu.org.uk>
To: airlied@linux.ie, dri-devel@lists.freedesktop.org
Subject: [PATCH 4/8] cdv: add the bits that don't need the new code
Date: Wed, 08 Aug 2012 14:54:41 +0100 [thread overview]
Message-ID: <20120808135427.974.22606.stgit@bluebook> (raw)
In-Reply-To: <20120808135225.974.25210.stgit@bluebook>
From: Alan Cox <alan@linux.intel.com>
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>
---
drivers/gpu/drm/gma500/cdv_device.c | 59 +++++++++++++++++
drivers/gpu/drm/gma500/cdv_intel_display.c | 99 +++++++++++++++++++++++++++-
drivers/gpu/drm/gma500/framebuffer.c | 4 +
drivers/gpu/drm/gma500/psb_intel_drv.h | 2 -
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 b7e7b49..e2fff24 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)
}
}
+static const char *force_audio_names[] = {
+ "off",
+ "auto",
+ "on",
+};
+
+void cdv_intel_attach_force_audio_property(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct drm_property *prop;
+ int i;
+
+ prop = dev_priv->force_audio_property;
+ if (prop == NULL) {
+ prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+ "audio",
+ ARRAY_SIZE(force_audio_names));
+ if (prop == NULL)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
+ drm_property_add_enum(prop, i, i-1, force_audio_names[i]);
+
+ dev_priv->force_audio_property = prop;
+ }
+ drm_connector_attach_property(connector, prop, 0);
+}
+
+
+static const char *broadcast_rgb_names[] = {
+ "Full",
+ "Limited 16:235",
+};
+
+void cdv_intel_attach_broadcast_rgb_property(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct drm_property *prop;
+ int i;
+
+ prop = dev_priv->broadcast_rgb_property;
+ if (prop == NULL) {
+ prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+ "Broadcast RGB",
+ ARRAY_SIZE(broadcast_rgb_names));
+ if (prop == NULL)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++)
+ drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]);
+
+ dev_priv->broadcast_rgb_property = prop;
+ }
+
+ drm_connector_attach_property(connector, prop, 0);
+}
+
/* Cedarview */
static const struct psb_offset cdv_regmap[2] = {
{
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c
index f16169c..2e0231e 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 {
static bool cdv_intel_find_best_PLL(const struct cdv_intel_limit_t *limit,
struct drm_crtc *crtc, int target, int refclk,
struct cdv_intel_clock_t *best_clock);
+static bool cdv_intel_find_dp_pll(const struct cdv_intel_limit_t *limit, struct drm_crtc *crtc, int target,
+ int refclk,
+ struct cdv_intel_clock_t *best_clock);
#define CDV_LIMIT_SINGLE_LVDS_96 0
#define CDV_LIMIT_SINGLE_LVDS_100 1
#define CDV_LIMIT_DAC_HDMI_27 2
#define CDV_LIMIT_DAC_HDMI_96 3
+#define CDV_LIMIT_DP_27 4
+#define CDV_LIMIT_DP_100 5
static const struct cdv_intel_limit_t cdv_intel_limits[] = {
{ /* CDV_SIGNLE_LVDS_96MHz */
@@ -123,6 +128,30 @@ static const struct cdv_intel_limit_t cdv_intel_limits[] = {
.p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5},
.find_pll = cdv_intel_find_best_PLL,
},
+ { /* CDV_DP_27MHz */
+ .dot = {.min = 160000, .max = 272000},
+ .vco = {.min = 1809000, .max = 3564000},
+ .n = {.min = 1, .max = 1},
+ .m = {.min = 67, .max = 132},
+ .m1 = {.min = 0, .max = 0},
+ .m2 = {.min = 65, .max = 130},
+ .p = {.min = 5, .max = 90},
+ .p1 = {.min = 1, .max = 9},
+ .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10},
+ .find_pll = cdv_intel_find_dp_pll,
+ },
+ { /* CDV_DP_100MHz */
+ .dot = {.min = 160000, .max = 272000},
+ .vco = {.min = 1800000, .max = 3600000},
+ .n = {.min = 2, .max = 6},
+ .m = {.min = 60, .max = 164},
+ .m1 = {.min = 0, .max = 0},
+ .m2 = {.min = 58, .max = 162},
+ .p = {.min = 5, .max = 100},
+ .p1 = {.min = 1, .max = 10},
+ .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 10},
+ .find_pll = cdv_intel_find_dp_pll,
+ }
};
#define _wait_for(COND, MS, W) ({ \
@@ -269,7 +298,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
ref_value &= ~(REF_CLK_MASK);
/* use DPLL_A for pipeB on CRT/HDMI */
- if (pipe == 1 && !is_lvds) {
+ if (pipe == 1 && !is_lvds && !(ddi_select & DP_MASK)) {
DRM_DEBUG_KMS("use DPLLA for pipe B\n");
ref_value |= REF_CLK_DPLLA;
} else {
@@ -409,6 +438,11 @@ static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc,
limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96];
else
limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100];
+ } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
+ if (refclk == 27000)
+ limit = &cdv_intel_limits[CDV_LIMIT_DP_27];
+ else
+ limit = &cdv_intel_limits[CDV_LIMIT_DP_100];
} else {
if (refclk == 27000)
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,
return err != target;
}
+static bool cdv_intel_find_dp_pll(const struct cdv_intel_limit_t *limit, struct drm_crtc *crtc, int target,
+ int refclk,
+ struct cdv_intel_clock_t *best_clock)
+{
+ struct cdv_intel_clock_t clock;
+ if (refclk == 27000) {
+ if (target < 200000) {
+ clock.p1 = 2;
+ clock.p2 = 10;
+ clock.n = 1;
+ clock.m1 = 0;
+ clock.m2 = 118;
+ } else {
+ clock.p1 = 1;
+ clock.p2 = 10;
+ clock.n = 1;
+ clock.m1 = 0;
+ clock.m2 = 98;
+ }
+ } else if (refclk == 100000) {
+ if (target < 200000) {
+ clock.p1 = 2;
+ clock.p2 = 10;
+ clock.n = 5;
+ clock.m1 = 0;
+ clock.m2 = 160;
+ } else {
+ clock.p1 = 1;
+ clock.p2 = 10;
+ clock.n = 5;
+ clock.m1 = 0;
+ clock.m2 = 133;
+ }
+ } else
+ return false;
+ clock.m = clock.m2 + 2;
+ clock.p = clock.p1 * clock.p2;
+ clock.vco = (refclk * clock.m) / clock.n;
+ clock.dot = clock.vco / clock.p;
+ memcpy(best_clock, &clock, sizeof(struct cdv_intel_clock_t));
+ return true;
+}
+
static int cdv_intel_pipe_set_base(struct drm_crtc *crtc,
int x, int y, struct drm_framebuffer *old_fb)
{
@@ -963,7 +1040,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
u32 dpll = 0, dspcntr, pipeconf;
bool ok;
bool is_crt = false, is_lvds = false, is_tv = false;
- bool is_hdmi = false;
+ bool is_hdmi = false, is_dp = false;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_connector *connector;
const struct cdv_intel_limit_t *limit;
@@ -991,6 +1068,9 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
case INTEL_OUTPUT_HDMI:
is_hdmi = true;
break;
+ case INTEL_OUTPUT_DISPLAYPORT:
+ is_dp = true;
+ break;
default:
DRM_ERROR("invalid output type.\n");
return 0;
@@ -1003,6 +1083,12 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
else
/* high-end sku, 27/100 mhz */
refclk = 27000;
+ if (is_dp) {
+ if (pipe == 0)
+ refclk = 27000;
+ else
+ refclk = 100000;
+ }
if (is_lvds && dev_priv->lvds_use_ssc) {
refclk = dev_priv->lvds_ssc_freq * 1000;
@@ -1028,6 +1114,15 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
}
/* dpll |= PLL_REF_INPUT_DREFCLK; */
+ if (is_dp) {
+/*FIXME cdv_intel_dp_set_m_n(crtc, mode, adjusted_mode); */
+ } else {
+ REG_WRITE(PIPE_GMCH_DATA_M(pipe), 0);
+ REG_WRITE(PIPE_GMCH_DATA_N(pipe), 0);
+ REG_WRITE(PIPE_DP_LINK_M(pipe), 0);
+ REG_WRITE(PIPE_DP_LINK_N(pipe), 0);
+ }
+
dpll |= DPLL_SYNCLOCK_ENABLE;
/* if (is_lvds)
dpll |= DPLLB_MODE_LVDS;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 5732b57..2de6b1f 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)
crtc_mask = dev_priv->ops->hdmi_mask;
clone_mask = (1 << INTEL_OUTPUT_HDMI);
break;
+ case INTEL_OUTPUT_DISPLAYPORT:
+ crtc_mask = (1 << 0) | (1 << 1);
+ clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
+ break;
}
encoder->possible_crtcs = crtc_mask;
encoder->possible_clones =
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index 73214e2..c574c01 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 {
u32 ddi_select; /* Channel info */
#define DDI0_SELECT 0x01
#define DDI1_SELECT 0x02
-#define DP_MASK 0x8000;
+#define DP_MASK 0x8000
#define DDI_MASK 0x03
void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */
next prev parent reply other threads:[~2012-08-08 12:56 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-08 13:53 [PATCH 1/8] Fix incorrect SR issue when disabling CRTC already in disabled state Alan Cox
2012-08-08 13:53 ` [PATCH 2/8] Program the DPLL lane based on the selected digitial port Alan Cox
2012-08-08 13:54 ` [PATCH 3/8] From: Zhao Yakui <yakui.zhao@intel.com> Alan Cox
2012-08-08 13:54 ` Alan Cox [this message]
2012-08-08 13:55 ` [PATCH 5/8] cdv: sync up and add the displayport code to the build Alan Cox
2012-08-08 13:55 ` [PATCH 6/8] cdv: enable the DisplayPort support Alan Cox
2012-08-08 13:55 ` [PATCH 7/8] cdv: Add eDP support Alan Cox
2012-08-08 13:57 ` [PATCH 8/8] From: Zhao Yakui <yakui.zhao@intel.com> Alan Cox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120808135427.974.22606.stgit@bluebook \
--to=alan@lxorguk.ukuu.org.uk \
--cc=airlied@linux.ie \
--cc=dri-devel@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.