9 static void intel_crt_dpms(struct drm_output *output, int mode)
11 drm_device_t *dev = output->dev;
12 drm_i915_private_t *dev_priv = dev->dev_private;
15 temp = I915_READ(ADPA);
16 temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
17 temp &= ~ADPA_DAC_ENABLE;
21 temp |= ADPA_DAC_ENABLE;
24 temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
27 temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
30 temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
34 I915_WRITE(ADPA, temp);
37 static void intel_crt_save(struct drm_output *output)
42 static void intel_crt_restore(struct drm_output *output)
47 static int intel_crt_mode_valid(struct drm_output *output,
48 struct drm_display_mode *mode)
50 if (mode->flags & V_DBLSCAN)
51 return MODE_NO_DBLESCAN;
53 if (mode->clock > 400000 || mode->clock < 25000)
54 return MODE_CLOCK_RANGE;
59 static bool intel_crt_mode_fixup(struct drm_output *output,
60 struct drm_display_mode *mode,
61 struct drm_display_mode *adjusted_mode)
66 static void intel_crt_mode_set(struct drm_output *output,
67 struct drm_display_mode *mode,
68 struct drm_display_mode *adjusted_mode)
70 drm_device_t *dev = output->dev;
71 struct drm_crtc *crtc = output->crtc;
72 struct intel_crtc *intel_crtc = crtc->driver_private;
73 drm_i915_private_t *dev_priv = dev->dev_private;
77 if (intel_crtc->pipe == 0)
78 dpll_md_reg = DPLL_A_MD;
80 dpll_md_reg = DPLL_B_MD;
83 * Disable separate mode multiplier used when cloning SDVO to CRT
84 * XXX this needs to be adjusted when we really are cloning
88 dpll_md = I915_READ(dpll_md_reg);
89 I915_WRITE(dpll_md_reg, dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
93 if (adjusted_mode->flags & V_PHSYNC)
94 adpa |= ADPA_HSYNC_ACTIVE_HIGH;
95 if (adjusted_mode->flags & V_PVSYNC)
96 adpa |= ADPA_VSYNC_ACTIVE_HIGH;
98 if (intel_crtc->pipe == 0)
99 adpa |= ADPA_PIPE_A_SELECT;
101 adpa |= ADPA_PIPE_B_SELECT;
103 I915_WRITE(ADPA, adpa);
107 * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
111 * \return TRUE if CRT is connected.
112 * \return FALSE if CRT is disconnected.
114 static bool intel_crt_detect_hotplug(struct drm_output *output)
116 drm_device_t *dev = output->dev;
117 // struct intel_output *intel_output = output->driver_private;
118 drm_i915_private_t *dev_priv = dev->dev_private;
120 const int timeout_ms = 1000;
121 int starttime, curtime;
123 temp = I915_READ(PORT_HOTPLUG_EN);
125 I915_WRITE(PORT_HOTPLUG_EN, temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
127 for (curtime = starttime = GetTimeInMillis();
128 (curtime - starttime) < timeout_ms; curtime = GetTimeInMillis())
130 if ((I915_READ(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT) == 0)
134 if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
135 CRT_HOTPLUG_MONITOR_COLOR)
143 static bool intel_crt_detect_ddc(struct drm_output *output)
145 struct intel_output *intel_output = output->driver_private;
147 /* CRT should always be at 0, but check anyway */
148 if (intel_output->type != INTEL_OUTPUT_ANALOG)
151 return intel_ddc_probe(output);
154 static enum drm_output_status intel_crt_detect(struct drm_output *output)
156 drm_device_t *dev = output->dev;
157 drm_i915_private_t *dev_priv = dev->dev_private;
159 if (IS_I945G(dev)| IS_I945GM(dev) || IS_I965G(dev)) {
160 if (intel_crt_detect_hotplug(output))
161 return output_status_connected;
163 return output_status_disconnected;
166 if (intel_crt_detect_ddc(output))
167 return output_status_connected;
169 /* TODO use load detect */
170 return output_status_unknown;
173 static void intel_crt_destroy(struct drm_output *output)
175 struct intel_output *intel_output = output->driver_private;
177 intel_i2c_destroy(intel_output->ddc_bus);
179 if (output->driver_private)
180 kfree(output->driver_private);
184 * Routines for controlling stuff on the analog port
186 static const struct drm_output_funcs intel_crt_output_funcs = {
187 .dpms = intel_crt_dpms,
188 .save = intel_crt_save,
189 .restore = intel_crt_restore,
190 .mode_valid = intel_crt_mode_valid,
191 .mode_fixup = intel_crt_mode_fixup,
192 .prepare = intel_output_prepare,
193 .mode_set = intel_crt_mode_set,
194 .commit = intel_output_commit,
195 .detect = intel_crt_detect,
196 .get_modes = intel_ddc_get_modes,
197 .cleanup = intel_crt_destroy,
200 void intel_crt_init(drm_device_t *dev)
202 struct drm_output *output;
203 struct intel_output *intel_output;
206 output = drm_output_create (dev, &intel_crt_output_funcs, "VGA");
208 intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL);
210 drm_output_destroy(output);
214 intel_output->type = INTEL_OUTPUT_ANALOG;
215 output->driver_private = intel_output;
216 output->interlace_allowed = 0;
217 output->doublescan_allowed = 0;
219 /* Set up the DDC bus. */
220 intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
221 if (!intel_output->ddc_bus) {
222 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "