[Intel-gfx] [PATCH 13/17] drm/i915: Hook up display port
Eric Anholt
eric at anholt.net
Fri Jun 5 16:02:45 CEST 2009
On Sat, 2009-05-30 at 20:42 -0700, Keith Packard wrote:
> ---
> drivers/gpu/drm/i915/intel_display.c | 91 +++++++++++++++++++-
> drivers/gpu/drm/i915/intel_dp.c | 62 +++++++++-----
> drivers/gpu/drm/i915/intel_dp.h | 16 ++--
> drivers/gpu/drm/i915/intel_dp_i2c.c | 157 ++++++++++++++++++++++------------
> drivers/gpu/drm/i915/intel_drv.h | 3 +
> 5 files changed, 242 insertions(+), 87 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 2b042ea..220d54d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -136,8 +136,9 @@ struct intel_limit {
> #define INTEL_LIMIT_G4X_HDMI_DAC 5
> #define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6
> #define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7
> -#define INTEL_LIMIT_IGD_SDVO_DAC 8
> -#define INTEL_LIMIT_IGD_LVDS 9
> +#define INTEL_LIMIT_G4X_DISPLAY_PORT 8
> +#define INTEL_LIMIT_IGD_SDVO_DAC 9
> +#define INTEL_LIMIT_IGD_LVDS 10
>
> /*The parameter is for SDVO on G4x platform*/
> #define G4X_DOT_SDVO_MIN 25000
> @@ -217,6 +218,25 @@ struct intel_limit {
> #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7
> #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0
>
> +/*The parameter is for DISPLAY PORT on G4x platform*/
> +#define G4X_DOT_DISPLAY_PORT_MIN 161670
> +#define G4X_DOT_DISPLAY_PORT_MAX 227000
> +#define G4X_N_DISPLAY_PORT_MIN 1
> +#define G4X_N_DISPLAY_PORT_MAX 2
> +#define G4X_M_DISPLAY_PORT_MIN 97
> +#define G4X_M_DISPLAY_PORT_MAX 108
> +#define G4X_M1_DISPLAY_PORT_MIN 0x10
> +#define G4X_M1_DISPLAY_PORT_MAX 0x12
> +#define G4X_M2_DISPLAY_PORT_MIN 0x05
> +#define G4X_M2_DISPLAY_PORT_MAX 0x06
> +#define G4X_P_DISPLAY_PORT_MIN 10
> +#define G4X_P_DISPLAY_PORT_MAX 20
> +#define G4X_P1_DISPLAY_PORT_MIN 1
> +#define G4X_P1_DISPLAY_PORT_MAX 2
> +#define G4X_P2_DISPLAY_PORT_SLOW 10
> +#define G4X_P2_DISPLAY_PORT_FAST 10
> +#define G4X_P2_DISPLAY_PORT_LIMIT 0
> +
> static bool
> intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
> int target, int refclk, intel_clock_t *best_clock);
> @@ -224,6 +244,10 @@ static bool
> intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
> int target, int refclk, intel_clock_t *best_clock);
>
> +static bool
> +intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc,
> + int target, int refclk, intel_clock_t *best_clock);
> +
> static const intel_limit_t intel_limits[] = {
> { /* INTEL_LIMIT_I8XX_DVO_DAC */
> .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
> @@ -357,6 +381,28 @@ static const intel_limit_t intel_limits[] = {
> },
> .find_pll = intel_g4x_find_best_PLL,
> },
> + { /* INTEL_LIMIT_G4X_DISPLAY_PORT */
> + .dot = { .min = G4X_DOT_DISPLAY_PORT_MIN,
> + .max = G4X_DOT_DISPLAY_PORT_MAX },
> + .vco = { .min = G4X_VCO_MIN,
> + .max = G4X_VCO_MAX},
> + .n = { .min = G4X_N_DISPLAY_PORT_MIN,
> + .max = G4X_N_DISPLAY_PORT_MAX },
> + .m = { .min = G4X_M_DISPLAY_PORT_MIN,
> + .max = G4X_M_DISPLAY_PORT_MAX },
> + .m1 = { .min = G4X_M1_DISPLAY_PORT_MIN,
> + .max = G4X_M1_DISPLAY_PORT_MAX },
> + .m2 = { .min = G4X_M2_DISPLAY_PORT_MIN,
> + .max = G4X_M2_DISPLAY_PORT_MAX },
> + .p = { .min = G4X_P_DISPLAY_PORT_MIN,
> + .max = G4X_P_DISPLAY_PORT_MAX },
> + .p1 = { .min = G4X_P1_DISPLAY_PORT_MIN,
> + .max = G4X_P1_DISPLAY_PORT_MAX},
> + .p2 = { .dot_limit = G4X_P2_DISPLAY_PORT_LIMIT,
> + .p2_slow = G4X_P2_DISPLAY_PORT_SLOW,
> + .p2_fast = G4X_P2_DISPLAY_PORT_FAST },
> + .find_pll = intel_find_pll_g4x_dp,
> + },
> { /* INTEL_LIMIT_IGD_SDVO */
> .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
> .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX },
> @@ -408,6 +454,8 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
> limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC];
> } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
> limit = &intel_limits[INTEL_LIMIT_G4X_SDVO];
> + } else if (intel_pipe_has_type (crtc, INTEL_OUTPUT_DISPLAYPORT)) {
> + limit = &intel_limits[INTEL_LIMIT_G4X_DISPLAY_PORT];
> } else /* The option is for other outputs */
> limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
>
> @@ -635,6 +683,35 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
> return found;
> }
>
> +/* DisplayPort has only two frequencies, 162MHz and 270MHz */
> +static bool
> +intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
> + int target, int refclk, intel_clock_t *best_clock)
> +{
> + intel_clock_t clock;
> + if (target < 200000) {
> + clock.dot = 161670;
> + clock.p = 20;
> + clock.p1 = 2;
> + clock.p2 = 10;
> + clock.n = 0x01;
> + clock.m = 97;
> + clock.m1 = 0x10;
> + clock.m2 = 0x05;
> + } else {
> + clock.dot = 270000;
> + clock.p = 10;
> + clock.p1 = 1;
> + clock.p2 = 10;
> + clock.n = 0x02;
> + clock.m = 108;
> + clock.m1 = 0x12;
> + clock.m2 = 0x06;
> + }
> + memcpy(best_clock, &clock, sizeof(intel_clock_t));
> + return true;
> +}
> +
> void
> intel_wait_for_vblank(struct drm_device *dev)
> {
> @@ -1108,6 +1185,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
> } else {
> refclk = 48000;
> }
> +
>
> /*
> * Returns a set of divisors for the desired target clock with the given
> @@ -1275,6 +1353,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
> I915_WRITE(LVDS, lvds);
> I915_READ(LVDS);
> }
> + if (is_dp)
> + intel_dp_set_m_n(crtc, mode, adjusted_mode);
>
> I915_WRITE(fp_reg, fp);
> I915_WRITE(dpll_reg, dpll);
> @@ -1920,7 +2000,7 @@ static void intel_setup_outputs(struct drm_device *dev)
> intel_dp_init(dev, DP_C);
> }
> if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED))
> - intel_dp_init(dev, DP_C);
> + intel_dp_init(dev, DP_D);
> } else
> intel_dvo_init(dev);
>
> @@ -1963,6 +2043,11 @@ static void intel_setup_outputs(struct drm_device *dev)
> (1 << 1));
> clone_mask = (1 << INTEL_OUTPUT_TVOUT);
> 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 = intel_connector_clones(dev, clone_mask);
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 50a75a1..ed3c7de 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -169,6 +169,12 @@ intel_dp_aux_ch(struct intel_output *intel_output,
> uint32_t ctl;
> uint32_t status;
>
> +// printk(KERN_ERR "dp_aux_ch 0x%08x send %d:",
> +// output_reg, send_bytes);
> +// for (i = 0; i < send_bytes; i++)
> +// printk(" %02x", send[i]);
> +// printk("\n");
No // comments in kernel code.
--
Eric Anholt
eric at anholt.net eric.anholt at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20090605/8236eff6/attachment.sig>
More information about the Intel-gfx
mailing list