Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  oaktrail_crtc.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright © 2009 Intel Corporation
 */


#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/pm_runtime.h>

#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_modeset_helper_vtables.h>

#include "framebuffer.h"
#include "gem.h"
#include "gma_display.h"
#include "power.h"
#include "psb_drv.h"
#include "psb_intel_drv.h"
#include "psb_intel_reg.h"

#define MRST_LIMIT_LVDS_100L 0
#define MRST_LIMIT_LVDS_83 1
#define MRST_LIMIT_LVDS_100 2
#define MRST_LIMIT_SDVO  3

#define MRST_DOT_MIN    19750
#define MRST_DOT_MAX    120000
#define MRST_M_MIN_100L      20
#define MRST_M_MIN_100      10
#define MRST_M_MIN_83      12
#define MRST_M_MAX_100L      34
#define MRST_M_MAX_100      17
#define MRST_M_MAX_83      20
#define MRST_P1_MIN      2
#define MRST_P1_MAX_0      7
#define MRST_P1_MAX_1      8

static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
        struct drm_crtc *crtc, int target,
        int refclk, struct gma_clock_t *best_clock);

static bool mrst_sdvo_find_best_pll(const struct gma_limit_t *limit,
        struct drm_crtc *crtc, int target,
        int refclk, struct gma_clock_t *best_clock);

static const struct gma_limit_t mrst_limits[] = {
 {   /* MRST_LIMIT_LVDS_100L */
  .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
  .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L},
  .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
  .find_pll = mrst_lvds_find_best_pll,
  },
 {   /* MRST_LIMIT_LVDS_83L */
  .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
  .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83},
  .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0},
  .find_pll = mrst_lvds_find_best_pll,
  },
 {   /* MRST_LIMIT_LVDS_100 */
  .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
  .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100},
  .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
  .find_pll = mrst_lvds_find_best_pll,
  },
 {   /* MRST_LIMIT_SDVO */
  .vco = {.min = 1400000, .max = 2800000},
  .n = {.min = 3, .max = 7},
  .m = {.min = 80, .max = 137},
  .p1 = {.min = 1, .max = 2},
  .p2 = {.dot_limit = 200000, .p2_slow = 10, .p2_fast = 10},
  .find_pll = mrst_sdvo_find_best_pll,
  },
};

#define MRST_M_MIN     10
static const u32 oaktrail_m_converts[] = {
 0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C,
 0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25,
 0x12, 0x09, 0x24, 0x32, 0x39, 0x1c,
};

static const struct gma_limit_t *mrst_limit(struct drm_crtc *crtc,
         int refclk)
{
 const struct gma_limit_t *limit = NULL;
 struct drm_device *dev = crtc->dev;
 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);

 if (gma_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
     || gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
  switch (dev_priv->core_freq) {
  case 100:
   limit = &mrst_limits[MRST_LIMIT_LVDS_100L];
   break;
  case 166:
   limit = &mrst_limits[MRST_LIMIT_LVDS_83];
   break;
  case 200:
   limit = &mrst_limits[MRST_LIMIT_LVDS_100];
   break;
  }
 } else if (gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
  limit = &mrst_limits[MRST_LIMIT_SDVO];
 } else {
  limit = NULL;
  dev_err(dev->dev, "mrst_limit Wrong display type.\n");
 }

 return limit;
}

/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
static void mrst_lvds_clock(int refclk, struct gma_clock_t *clock)
{
 clock->dot = (refclk * clock->m) / (14 * clock->p1);
}

static void mrst_print_pll(struct gma_clock_t *clock)
{
 DRM_DEBUG_DRIVER("dotclock=%d, m=%d, m1=%d, m2=%d, n=%d, p1=%d, p2=%d\n",
    clock->dot, clock->m, clock->m1, clock->m2, clock->n,
    clock->p1, clock->p2);
}

static bool mrst_sdvo_find_best_pll(const struct gma_limit_t *limit,
        struct drm_crtc *crtc, int target,
        int refclk, struct gma_clock_t *best_clock)
{
 struct gma_clock_t clock;
 u32 target_vco, actual_freq;
 s32 freq_error, min_error = 100000;

 memset(best_clock, 0, sizeof(*best_clock));
 memset(&clock, 0, sizeof(clock));

 for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
  for (clock.n = limit->n.min; clock.n <= limit->n.max;
       clock.n++) {
   for (clock.p1 = limit->p1.min;
        clock.p1 <= limit->p1.max; clock.p1++) {
    /* p2 value always stored in p2_slow on SDVO */
    clock.p = clock.p1 * limit->p2.p2_slow;
    target_vco = target * clock.p;

    /* VCO will increase at this point so break */
    if (target_vco > limit->vco.max)
     break;

    if (target_vco < limit->vco.min)
     continue;

    actual_freq = (refclk * clock.m) /
           (clock.n * clock.p);
    freq_error = 10000 -
          ((target * 10000) / actual_freq);

    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
 */

static bool mrst_lvds_find_best_pll(const struct 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;

 memset(best_clock, 0, sizeof(*best_clock));
 memset(&clock, 0, sizeof(clock));

 for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
  for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
       clock.p1++) {
   int this_err;

   mrst_lvds_clock(refclk, &clock);

   this_err = abs(clock.dot - target);
   if (this_err < err) {
    *best_clock = clock;
    err = this_err;
   }
  }
 }
 return 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.
 */

static void 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;
 const struct 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);
   }

   /* Enable the pipe */
   temp = REG_READ_WITH_AUX(map->conf, i);
   if ((temp & PIPEACONF_ENABLE) == 0) {
    REG_WRITE_WITH_AUX(map->conf,
         temp | PIPEACONF_ENABLE, i);
   }

   /* Enable the 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_WITH_AUX(map->base, i), i);
   }

  }
  gma_crtc_load_lut(crtc);

  /* 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);

   temp = REG_READ_WITH_AUX(map->dpll, i);
   if ((temp & DPLL_VCO_ENABLE) != 0) {
    REG_WRITE_WITH_AUX(map->dpll,
         temp & ~DPLL_VCO_ENABLE, i);
    REG_READ_WITH_AUX(map->dpll, i);
   }

   /* 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
 */

static int 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;
}

static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
         struct drm_display_mode *mode,
         struct drm_display_mode *adjusted_mode,
         int x, int y,
         struct drm_framebuffer *old_fb)
{
 struct drm_device *dev = crtc->dev;
 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
 int pipe = gma_crtc->pipe;
 const struct psb_offset *map = &dev_priv->regmap[pipe];
 int refclk = 0;
 struct gma_clock_t clock;
 const struct gma_limit_t *limit;
 u32 dpll = 0, fp = 0, dspcntr, pipeconf;
 bool ok, is_sdvo = false;
 bool is_lvds = false;
 bool is_mipi = false;
 struct gma_encoder *gma_encoder = NULL;
 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
 struct drm_connector_list_iter conn_iter;
 struct drm_connector *connector;
 int i;
 int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;

 if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
  return oaktrail_crtc_hdmi_mode_set(crtc, mode, adjusted_mode, x, y, old_fb);

 if (!gma_power_begin(dev, true))
  return 0;

 drm_mode_copy(&gma_crtc->saved_mode, mode);
 drm_mode_copy(&gma_crtc->saved_adjusted_mode, adjusted_mode);

 drm_connector_list_iter_begin(dev, &conn_iter);
 drm_for_each_connector_iter(connector, &conn_iter) {
  if (!connector->encoder || connector->encoder->crtc != crtc)
   continue;

  gma_encoder = gma_attached_encoder(connector);

  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;

  offsetX = (adjusted_mode->crtc_hdisplay -
      mode->crtc_hdisplay) / 2;
  offsetY = (adjusted_mode->crtc_vdisplay -
      mode->crtc_vdisplay) / 2;

  for (i = 0; i <= need_aux; i++) {
   REG_WRITE_WITH_AUX(map->htotal, (mode->crtc_hdisplay - 1) |
    ((adjusted_mode->crtc_htotal - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->vtotal, (mode->crtc_vdisplay - 1) |
    ((adjusted_mode->crtc_vtotal - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->hblank,
    (adjusted_mode->crtc_hblank_start - offsetX - 1) |
    ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->hsync,
    (adjusted_mode->crtc_hsync_start - offsetX - 1) |
    ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->vblank,
    (adjusted_mode->crtc_vblank_start - offsetY - 1) |
    ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->vsync,
    (adjusted_mode->crtc_vsync_start - offsetY - 1) |
    ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16), i);
  }
 } else {
  for (i = 0; i <= need_aux; i++) {
   REG_WRITE_WITH_AUX(map->htotal, (adjusted_mode->crtc_hdisplay - 1) |
    ((adjusted_mode->crtc_htotal - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) |
    ((adjusted_mode->crtc_vtotal - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->hblank, (adjusted_mode->crtc_hblank_start - 1) |
    ((adjusted_mode->crtc_hblank_end - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->hsync, (adjusted_mode->crtc_hsync_start - 1) |
    ((adjusted_mode->crtc_hsync_end - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->vblank, (adjusted_mode->crtc_vblank_start - 1) |
    ((adjusted_mode->crtc_vblank_end - 1) << 16), i);
   REG_WRITE_WITH_AUX(map->vsync, (adjusted_mode->crtc_vsync_start - 1) |
    ((adjusted_mode->crtc_vsync_end - 1) << 16), i);
  }
 }

 /* Flush the plane changes */
 {
  const struct drm_crtc_helper_funcs *crtc_funcs =
      crtc->helper_private;
  crtc_funcs->mode_set_base(crtc, x, y, old_fb);
 }

 /* setup pipeconf */
 pipeconf = REG_READ(map->conf);

 /* Set up the display plane register */
 dspcntr = REG_READ(map->cntr);
 dspcntr |= DISPPLANE_GAMMA_ENABLE;

 if (pipe == 0)
  dspcntr |= DISPPLANE_SEL_PIPE_A;
 else
  dspcntr |= DISPPLANE_SEL_PIPE_B;

 if (is_mipi)
  goto oaktrail_crtc_mode_set_exit;


 dpll = 0;  /*BIT16 = 0 for 100MHz reference */

 refclk = is_sdvo ? 96000 : dev_priv->core_freq * 1000;
 limit = mrst_limit(crtc, refclk);
 ok = limit->find_pll(limit, crtc, adjusted_mode->clock,
        refclk, &clock);

 if (is_sdvo) {
  /* Convert calculated values to register values */
  clock.p1 = (1L << (clock.p1 - 1));
  clock.m -= 2;
  clock.n = (1L << (clock.n - 1));
 }

 if (!ok)
  DRM_ERROR("Failed to find proper PLL settings");

 mrst_print_pll(&clock);

 if (is_sdvo)
  fp = clock.n << 16 | clock.m;
 else
  fp = oaktrail_m_converts[(clock.m - MRST_M_MIN)] << 8;

 dpll |= DPLL_VGA_MODE_DIS;


 dpll |= DPLL_VCO_ENABLE;

 if (is_lvds)
  dpll |= DPLLA_MODE_LVDS;
 else
  dpll |= DPLLB_MODE_DAC_SERIAL;

 if (is_sdvo) {
  int sdvo_pixel_multiply =
      adjusted_mode->clock / mode->clock;

  dpll |= DPLL_DVO_HIGH_SPEED;
  dpll |=
      (sdvo_pixel_multiply -
       1) << SDVO_MULTIPLIER_SHIFT_HIRES;
 }


 /* compute bitmask from p1 value */
 if (is_sdvo)
  dpll |= clock.p1 << 16; // dpll |= (1 << (clock.p1 - 1)) << 16;
 else
  dpll |= (1 << (clock.p1 - 2)) << 17;

 dpll |= DPLL_VCO_ENABLE;

 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);

  REG_WRITE_WITH_AUX(map->conf, pipeconf, i);
  REG_READ_WITH_AUX(map->conf, i);
  gma_wait_for_vblank(dev);

  REG_WRITE_WITH_AUX(map->cntr, dspcntr, i);
  gma_wait_for_vblank(dev);
 }

oaktrail_crtc_mode_set_exit:
 gma_power_end(dev);
 return 0;
}

static int oaktrail_pipe_set_base(struct drm_crtc *crtc,
       int x, int y, struct drm_framebuffer *old_fb)
{
 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);
 struct drm_framebuffer *fb = crtc->primary->fb;
 int pipe = gma_crtc->pipe;
 const struct psb_offset *map = &dev_priv->regmap[pipe];
 unsigned long start, offset;

 u32 dspcntr;
 int ret = 0;

 /* no fb bound */
 if (!fb) {
  dev_dbg(dev->dev, "No FB bound\n");
  return 0;
 }

 if (!gma_power_begin(dev, true))
  return 0;

 start = to_psb_gem_object(fb->obj[0])->offset;
 offset = y * fb->pitches[0] + x * fb->format->cpp[0];

 REG_WRITE(map->stride, fb->pitches[0]);

 dspcntr = REG_READ(map->cntr);
 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;

 switch (fb->format->cpp[0] * 8) {
 case 8:
  dspcntr |= DISPPLANE_8BPP;
  break;
 case 16:
  if (fb->format->depth == 15)
   dspcntr |= DISPPLANE_15_16BPP;
  else
   dspcntr |= DISPPLANE_16BPP;
  break;
 case 24:
 case 32:
  dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
  break;
 default:
  dev_err(dev->dev, "Unknown color depth\n");
  ret = -EINVAL;
  goto pipe_set_base_exit;
 }
 REG_WRITE(map->cntr, dspcntr);

 REG_WRITE(map->base, offset);
 REG_READ(map->base);
 REG_WRITE(map->surf, start);
 REG_READ(map->surf);

pipe_set_base_exit:
 gma_power_end(dev);
 return ret;
}

const struct drm_crtc_helper_funcs oaktrail_helper_funcs = {
 .dpms = oaktrail_crtc_dpms,
 .mode_set = oaktrail_crtc_mode_set,
 .mode_set_base = oaktrail_pipe_set_base,
 .prepare = gma_crtc_prepare,
 .commit = gma_crtc_commit,
};

Messung V0.5
C=95 H=88 G=91

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge