if (freq_error < -min_error) { /* freq_error will start to decrease at
this point so break */ break;
}
if (freq_error < 0)
freq_error = -freq_error;
if (freq_error < min_error) {
min_error = freq_error;
*best_clock = clock;
}
}
} if (min_error == 0) break;
}
return min_error == 0;
}
/* * Returns a set of divisors for the desired target clock with the given refclk, * or FALSE. Divisor values are the actual divisors for
*/ staticbool mrst_lvds_find_best_pll(conststruct gma_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, struct gma_clock_t *best_clock)
{ struct gma_clock_t clock; int err = target;
/* * Sets the power management mode of the pipe and plane. * * This code should probably grow support for turning the cursor off and back * on appropriately at the same time as we're turning the pipe off/on.
*/ staticvoid oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
{ struct drm_device *dev = crtc->dev; struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct gma_crtc *gma_crtc = to_gma_crtc(crtc); int pipe = gma_crtc->pipe; conststruct psb_offset *map = &dev_priv->regmap[pipe];
u32 temp; int i; int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;
if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
oaktrail_crtc_hdmi_dpms(crtc, mode); return;
}
if (!gma_power_begin(dev, true)) return;
/* XXX: When our outputs are all unaware of DPMS modes other than off * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
*/ switch (mode) { case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: for (i = 0; i <= need_aux; i++) { /* Enable the DPLL */
temp = REG_READ_WITH_AUX(map->dpll, i); if ((temp & DPLL_VCO_ENABLE) == 0) {
REG_WRITE_WITH_AUX(map->dpll, temp, i);
REG_READ_WITH_AUX(map->dpll, i); /* Wait for the clocks to stabilize. */
udelay(150);
REG_WRITE_WITH_AUX(map->dpll,
temp | DPLL_VCO_ENABLE, i);
REG_READ_WITH_AUX(map->dpll, i); /* Wait for the clocks to stabilize. */
udelay(150);
REG_WRITE_WITH_AUX(map->dpll,
temp | DPLL_VCO_ENABLE, i);
REG_READ_WITH_AUX(map->dpll, i); /* Wait for the clocks to stabilize. */
udelay(150);
}
/* Give the overlay scaler a chance to enable
if it's on this pipe */ /* psb_intel_crtc_dpms_video(crtc, true); TODO */ break; case DRM_MODE_DPMS_OFF: /* Give the overlay scaler a chance to disable
* if it's on this pipe */ /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
for (i = 0; i <= need_aux; i++) { /* Disable the VGA plane that we never use */
REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i); /* Disable display plane */
temp = REG_READ_WITH_AUX(map->cntr, i); if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
REG_WRITE_WITH_AUX(map->cntr,
temp & ~DISPLAY_PLANE_ENABLE, i); /* Flush the plane changes */
REG_WRITE_WITH_AUX(map->base,
REG_READ(map->base), i);
REG_READ_WITH_AUX(map->base, i);
}
/* Next, disable display pipes */
temp = REG_READ_WITH_AUX(map->conf, i); if ((temp & PIPEACONF_ENABLE) != 0) {
REG_WRITE_WITH_AUX(map->conf,
temp & ~PIPEACONF_ENABLE, i);
REG_READ_WITH_AUX(map->conf, i);
} /* Wait for the pipe disable to take effect. */
gma_wait_for_vblank(dev);
/* Wait for the clocks to turn off. */
udelay(150);
} break;
}
/* Set FIFO Watermarks (values taken from EMGD) */
REG_WRITE(DSPARB, 0x3f80);
REG_WRITE(DSPFW1, 0x3f8f0404);
REG_WRITE(DSPFW2, 0x04040f04);
REG_WRITE(DSPFW3, 0x0);
REG_WRITE(DSPFW4, 0x04040404);
REG_WRITE(DSPFW5, 0x04040404);
REG_WRITE(DSPFW6, 0x78);
REG_WRITE(DSPCHICKENBIT, REG_READ(DSPCHICKENBIT) | 0xc040);
gma_power_end(dev);
}
/* * Return the pipe currently connected to the panel fitter, * or -1 if the panel fitter is not present or not in use
*/ staticint oaktrail_panel_fitter_pipe(struct drm_device *dev)
{
u32 pfit_control;
pfit_control = REG_READ(PFIT_CONTROL);
/* See if the panel fitter is in use */ if ((pfit_control & PFIT_ENABLE) == 0) return -1; return (pfit_control >> 29) & 3;
}
switch (gma_encoder->type) { case INTEL_OUTPUT_LVDS:
is_lvds = true; break; case INTEL_OUTPUT_SDVO:
is_sdvo = true; break; case INTEL_OUTPUT_MIPI:
is_mipi = true; break;
}
break;
}
if (gma_encoder)
drm_object_property_get_value(&connector->base,
dev->mode_config.scaling_mode_property, &scalingType);
drm_connector_list_iter_end(&conn_iter);
/* Disable the VGA plane that we never use */ for (i = 0; i <= need_aux; i++)
REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i);
/* Disable the panel fitter if it was on our pipe */ if (oaktrail_panel_fitter_pipe(dev) == pipe)
REG_WRITE(PFIT_CONTROL, 0);
for (i = 0; i <= need_aux; i++) {
REG_WRITE_WITH_AUX(map->src, ((mode->crtc_hdisplay - 1) << 16) |
(mode->crtc_vdisplay - 1), i);
}
if (scalingType == DRM_MODE_SCALE_NO_SCALE) { /* Moorestown doesn't have register support for centering so * we need to mess with the h/vblank and h/vsync start and
* ends to get centering */ int offsetX = 0, offsetY = 0;
if (dpll & DPLL_VCO_ENABLE) { for (i = 0; i <= need_aux; i++) {
REG_WRITE_WITH_AUX(map->fp0, fp, i);
REG_WRITE_WITH_AUX(map->dpll, dpll & ~DPLL_VCO_ENABLE, i);
REG_READ_WITH_AUX(map->dpll, i); /* Check the DPLLA lock bit PIPEACONF[29] */
udelay(150);
}
}
for (i = 0; i <= need_aux; i++) {
REG_WRITE_WITH_AUX(map->fp0, fp, i);
REG_WRITE_WITH_AUX(map->dpll, dpll, i);
REG_READ_WITH_AUX(map->dpll, i); /* Wait for the clocks to stabilize. */
udelay(150);
/* write it again -- the BIOS does, after all */
REG_WRITE_WITH_AUX(map->dpll, dpll, i);
REG_READ_WITH_AUX(map->dpll, i); /* Wait for the clocks to stabilize. */
udelay(150);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.