54,6 → 54,13 |
.dev_ops = &ch7xxx_ops, |
}, |
{ |
.type = INTEL_DVO_CHIP_TMDS, |
.name = "ch7xxx", |
.dvo_reg = DVOC, |
.slave_addr = 0x75, /* For some ch7010 */ |
.dev_ops = &ch7xxx_ops, |
}, |
{ |
.type = INTEL_DVO_CHIP_LVDS, |
.name = "ivch", |
.dvo_reg = DVOA, |
93,15 → 100,14 |
bool panel_wants_dither; |
}; |
|
static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder) |
static struct intel_dvo *enc_to_dvo(struct intel_encoder *encoder) |
{ |
return container_of(encoder, struct intel_dvo, base.base); |
return container_of(encoder, struct intel_dvo, base); |
} |
|
static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector) |
{ |
return container_of(intel_attached_encoder(connector), |
struct intel_dvo, base); |
return enc_to_dvo(intel_attached_encoder(connector)); |
} |
|
static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector) |
116,7 → 122,7 |
{ |
struct drm_device *dev = encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); |
struct intel_dvo *intel_dvo = enc_to_dvo(encoder); |
u32 tmp; |
|
tmp = I915_READ(intel_dvo->dev.dvo_reg); |
129,10 → 135,30 |
return true; |
} |
|
static void intel_dvo_get_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config) |
{ |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
struct intel_dvo *intel_dvo = enc_to_dvo(encoder); |
u32 tmp, flags = 0; |
|
tmp = I915_READ(intel_dvo->dev.dvo_reg); |
if (tmp & DVO_HSYNC_ACTIVE_HIGH) |
flags |= DRM_MODE_FLAG_PHSYNC; |
else |
flags |= DRM_MODE_FLAG_NHSYNC; |
if (tmp & DVO_VSYNC_ACTIVE_HIGH) |
flags |= DRM_MODE_FLAG_PVSYNC; |
else |
flags |= DRM_MODE_FLAG_NVSYNC; |
|
pipe_config->adjusted_mode.flags |= flags; |
} |
|
static void intel_disable_dvo(struct intel_encoder *encoder) |
{ |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); |
struct intel_dvo *intel_dvo = enc_to_dvo(encoder); |
u32 dvo_reg = intel_dvo->dev.dvo_reg; |
u32 temp = I915_READ(dvo_reg); |
|
144,7 → 170,7 |
static void intel_enable_dvo(struct intel_encoder *encoder) |
{ |
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); |
struct intel_dvo *intel_dvo = enc_to_dvo(encoder); |
u32 dvo_reg = intel_dvo->dev.dvo_reg; |
u32 temp = I915_READ(dvo_reg); |
|
153,6 → 179,7 |
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); |
} |
|
/* Special dpms function to support cloning between dvo/sdvo/crt. */ |
static void intel_dvo_dpms(struct drm_connector *connector, int mode) |
{ |
struct intel_dvo *intel_dvo = intel_attached_dvo(connector); |
174,6 → 201,8 |
return; |
} |
|
/* We call connector dpms manually below in case pipe dpms doesn't |
* change due to cloning. */ |
if (mode == DRM_MODE_DPMS_ON) { |
intel_dvo->base.connectors_active = true; |
|
211,11 → 240,11 |
return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode); |
} |
|
static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, |
const struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
static bool intel_dvo_compute_config(struct intel_encoder *encoder, |
struct intel_crtc_config *pipe_config) |
{ |
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
struct intel_dvo *intel_dvo = enc_to_dvo(encoder); |
struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; |
|
/* If we have timings from the BIOS for the panel, put them in |
* to the adjusted mode. The CRTC will be set up for this mode, |
234,26 → 263,28 |
C(vtotal); |
C(clock); |
#undef C |
|
drm_mode_set_crtcinfo(adjusted_mode, 0); |
} |
|
if (intel_dvo->dev.dev_ops->mode_fixup) |
return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode); |
return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, |
&pipe_config->requested_mode, |
adjusted_mode); |
|
return true; |
} |
|
static void intel_dvo_mode_set(struct drm_encoder *encoder, |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
static void intel_dvo_mode_set(struct intel_encoder *encoder) |
{ |
struct drm_device *dev = encoder->dev; |
struct drm_device *dev = encoder->base.dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
int pipe = intel_crtc->pipe; |
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; |
struct intel_dvo *intel_dvo = enc_to_dvo(encoder); |
int pipe = crtc->pipe; |
u32 dvo_val; |
u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg; |
int dpll_reg = DPLL(pipe); |
|
switch (dvo_reg) { |
case DVOA: |
268,7 → 299,9 |
break; |
} |
|
intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode); |
intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, |
&crtc->config.requested_mode, |
adjusted_mode); |
|
/* Save the data order, since I don't know what it should be set to. */ |
dvo_val = I915_READ(dvo_reg) & |
284,8 → 317,6 |
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
dvo_val |= DVO_VSYNC_ACTIVE_HIGH; |
|
I915_WRITE(dpll_reg, I915_READ(dpll_reg) | DPLL_DVO_HIGH_SPEED); |
|
/*I915_WRITE(DVOB_SRCDIM, |
(adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | |
(adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/ |
305,6 → 336,8 |
intel_dvo_detect(struct drm_connector *connector, bool force) |
{ |
struct intel_dvo *intel_dvo = intel_attached_dvo(connector); |
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
connector->base.id, drm_get_connector_name(connector)); |
return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); |
} |
|
342,11 → 375,6 |
kfree(connector); |
} |
|
static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { |
.mode_fixup = intel_dvo_mode_fixup, |
.mode_set = intel_dvo_mode_set, |
}; |
|
static const struct drm_connector_funcs intel_dvo_connector_funcs = { |
.dpms = intel_dvo_dpms, |
.detect = intel_dvo_detect, |
362,7 → 390,7 |
|
static void intel_dvo_enc_destroy(struct drm_encoder *encoder) |
{ |
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
struct intel_dvo *intel_dvo = enc_to_dvo(to_intel_encoder(encoder)); |
|
if (intel_dvo->dev.dev_ops->destroy) |
intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev); |
440,6 → 468,9 |
intel_encoder->disable = intel_disable_dvo; |
intel_encoder->enable = intel_enable_dvo; |
intel_encoder->get_hw_state = intel_dvo_get_hw_state; |
intel_encoder->get_config = intel_dvo_get_config; |
intel_encoder->compute_config = intel_dvo_compute_config; |
intel_encoder->mode_set = intel_dvo_mode_set; |
intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; |
|
/* Now, try to find a controller */ |
506,9 → 537,6 |
connector->interlace_allowed = false; |
connector->doublescan_allowed = false; |
|
drm_encoder_helper_add(&intel_encoder->base, |
&intel_dvo_helper_funcs); |
|
intel_connector_attach_encoder(intel_connector, intel_encoder); |
if (dvo->type == INTEL_DVO_CHIP_LVDS) { |
/* For our LVDS chipsets, we should hopefully be able |