root/drivers/gpu/drm/gma500/gma_display.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gma_pipe_has_type
  2. gma_wait_for_vblank
  3. gma_pipe_set_base
  4. gma_crtc_load_lut
  5. gma_crtc_gamma_set
  6. gma_crtc_dpms
  7. gma_crtc_cursor_set
  8. gma_crtc_cursor_move
  9. gma_crtc_prepare
  10. gma_crtc_commit
  11. gma_crtc_disable
  12. gma_crtc_destroy
  13. gma_crtc_set_config
  14. gma_crtc_save
  15. gma_crtc_restore
  16. gma_encoder_prepare
  17. gma_encoder_commit
  18. gma_encoder_destroy
  19. gma_best_encoder
  20. gma_connector_attach_encoder
  21. gma_pll_is_valid
  22. gma_find_best_pll

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright © 2006-2011 Intel Corporation
   4  *
   5  * Authors:
   6  *      Eric Anholt <eric@anholt.net>
   7  *      Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
   8  */
   9 
  10 #include <linux/delay.h>
  11 #include <linux/highmem.h>
  12 
  13 #include <drm/drm_crtc.h>
  14 #include <drm/drm_fourcc.h>
  15 #include <drm/drm_vblank.h>
  16 
  17 #include "framebuffer.h"
  18 #include "gma_display.h"
  19 #include "psb_drv.h"
  20 #include "psb_intel_drv.h"
  21 #include "psb_intel_reg.h"
  22 
  23 /**
  24  * Returns whether any output on the specified pipe is of the specified type
  25  */
  26 bool gma_pipe_has_type(struct drm_crtc *crtc, int type)
  27 {
  28         struct drm_device *dev = crtc->dev;
  29         struct drm_mode_config *mode_config = &dev->mode_config;
  30         struct drm_connector *l_entry;
  31 
  32         list_for_each_entry(l_entry, &mode_config->connector_list, head) {
  33                 if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
  34                         struct gma_encoder *gma_encoder =
  35                                                 gma_attached_encoder(l_entry);
  36                         if (gma_encoder->type == type)
  37                                 return true;
  38                 }
  39         }
  40 
  41         return false;
  42 }
  43 
  44 void gma_wait_for_vblank(struct drm_device *dev)
  45 {
  46         /* Wait for 20ms, i.e. one cycle at 50hz. */
  47         mdelay(20);
  48 }
  49 
  50 int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y,
  51                       struct drm_framebuffer *old_fb)
  52 {
  53         struct drm_device *dev = crtc->dev;
  54         struct drm_psb_private *dev_priv = dev->dev_private;
  55         struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
  56         struct drm_framebuffer *fb = crtc->primary->fb;
  57         struct gtt_range *gtt;
  58         int pipe = gma_crtc->pipe;
  59         const struct psb_offset *map = &dev_priv->regmap[pipe];
  60         unsigned long start, offset;
  61         u32 dspcntr;
  62         int ret = 0;
  63 
  64         if (!gma_power_begin(dev, true))
  65                 return 0;
  66 
  67         /* no fb bound */
  68         if (!fb) {
  69                 dev_err(dev->dev, "No FB bound\n");
  70                 goto gma_pipe_cleaner;
  71         }
  72 
  73         gtt = to_gtt_range(fb->obj[0]);
  74 
  75         /* We are displaying this buffer, make sure it is actually loaded
  76            into the GTT */
  77         ret = psb_gtt_pin(gtt);
  78         if (ret < 0)
  79                 goto gma_pipe_set_base_exit;
  80         start = gtt->offset;
  81         offset = y * fb->pitches[0] + x * fb->format->cpp[0];
  82 
  83         REG_WRITE(map->stride, fb->pitches[0]);
  84 
  85         dspcntr = REG_READ(map->cntr);
  86         dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
  87 
  88         switch (fb->format->cpp[0] * 8) {
  89         case 8:
  90                 dspcntr |= DISPPLANE_8BPP;
  91                 break;
  92         case 16:
  93                 if (fb->format->depth == 15)
  94                         dspcntr |= DISPPLANE_15_16BPP;
  95                 else
  96                         dspcntr |= DISPPLANE_16BPP;
  97                 break;
  98         case 24:
  99         case 32:
 100                 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 101                 break;
 102         default:
 103                 dev_err(dev->dev, "Unknown color depth\n");
 104                 ret = -EINVAL;
 105                 goto gma_pipe_set_base_exit;
 106         }
 107         REG_WRITE(map->cntr, dspcntr);
 108 
 109         dev_dbg(dev->dev,
 110                 "Writing base %08lX %08lX %d %d\n", start, offset, x, y);
 111 
 112         /* FIXME: Investigate whether this really is the base for psb and why
 113                   the linear offset is named base for the other chips. map->surf
 114                   should be the base and map->linoff the offset for all chips */
 115         if (IS_PSB(dev)) {
 116                 REG_WRITE(map->base, offset + start);
 117                 REG_READ(map->base);
 118         } else {
 119                 REG_WRITE(map->base, offset);
 120                 REG_READ(map->base);
 121                 REG_WRITE(map->surf, start);
 122                 REG_READ(map->surf);
 123         }
 124 
 125 gma_pipe_cleaner:
 126         /* If there was a previous display we can now unpin it */
 127         if (old_fb)
 128                 psb_gtt_unpin(to_gtt_range(old_fb->obj[0]));
 129 
 130 gma_pipe_set_base_exit:
 131         gma_power_end(dev);
 132         return ret;
 133 }
 134 
 135 /* Loads the palette/gamma unit for the CRTC with the prepared values */
 136 void gma_crtc_load_lut(struct drm_crtc *crtc)
 137 {
 138         struct drm_device *dev = crtc->dev;
 139         struct drm_psb_private *dev_priv = dev->dev_private;
 140         struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
 141         const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
 142         int palreg = map->palette;
 143         u16 *r, *g, *b;
 144         int i;
 145 
 146         /* The clocks have to be on to load the palette. */
 147         if (!crtc->enabled)
 148                 return;
 149 
 150         r = crtc->gamma_store;
 151         g = r + crtc->gamma_size;
 152         b = g + crtc->gamma_size;
 153 
 154         if (gma_power_begin(dev, false)) {
 155                 for (i = 0; i < 256; i++) {
 156                         REG_WRITE(palreg + 4 * i,
 157                                   (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
 158                                   (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
 159                                   ((*b++ >> 8) + gma_crtc->lut_adj[i]));
 160                 }
 161                 gma_power_end(dev);
 162         } else {
 163                 for (i = 0; i < 256; i++) {
 164                         /* FIXME: Why pipe[0] and not pipe[..._crtc->pipe]? */
 165                         dev_priv->regs.pipe[0].palette[i] =
 166                                 (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
 167                                 (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
 168                                 ((*b++ >> 8) + gma_crtc->lut_adj[i]);
 169                 }
 170 
 171         }
 172 }
 173 
 174 int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue,
 175                        u32 size,
 176                        struct drm_modeset_acquire_ctx *ctx)
 177 {
 178         gma_crtc_load_lut(crtc);
 179 
 180         return 0;
 181 }
 182 
 183 /**
 184  * Sets the power management mode of the pipe and plane.
 185  *
 186  * This code should probably grow support for turning the cursor off and back
 187  * on appropriately at the same time as we're turning the pipe off/on.
 188  */
 189 void gma_crtc_dpms(struct drm_crtc *crtc, int mode)
 190 {
 191         struct drm_device *dev = crtc->dev;
 192         struct drm_psb_private *dev_priv = dev->dev_private;
 193         struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
 194         int pipe = gma_crtc->pipe;
 195         const struct psb_offset *map = &dev_priv->regmap[pipe];
 196         u32 temp;
 197 
 198         /* XXX: When our outputs are all unaware of DPMS modes other than off
 199          * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
 200          */
 201 
 202         if (IS_CDV(dev))
 203                 dev_priv->ops->disable_sr(dev);
 204 
 205         switch (mode) {
 206         case DRM_MODE_DPMS_ON:
 207         case DRM_MODE_DPMS_STANDBY:
 208         case DRM_MODE_DPMS_SUSPEND:
 209                 if (gma_crtc->active)
 210                         break;
 211 
 212                 gma_crtc->active = true;
 213 
 214                 /* Enable the DPLL */
 215                 temp = REG_READ(map->dpll);
 216                 if ((temp & DPLL_VCO_ENABLE) == 0) {
 217                         REG_WRITE(map->dpll, temp);
 218                         REG_READ(map->dpll);
 219                         /* Wait for the clocks to stabilize. */
 220                         udelay(150);
 221                         REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE);
 222                         REG_READ(map->dpll);
 223                         /* Wait for the clocks to stabilize. */
 224                         udelay(150);
 225                         REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE);
 226                         REG_READ(map->dpll);
 227                         /* Wait for the clocks to stabilize. */
 228                         udelay(150);
 229                 }
 230 
 231                 /* Enable the plane */
 232                 temp = REG_READ(map->cntr);
 233                 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
 234                         REG_WRITE(map->cntr,
 235                                   temp | DISPLAY_PLANE_ENABLE);
 236                         /* Flush the plane changes */
 237                         REG_WRITE(map->base, REG_READ(map->base));
 238                 }
 239 
 240                 udelay(150);
 241 
 242                 /* Enable the pipe */
 243                 temp = REG_READ(map->conf);
 244                 if ((temp & PIPEACONF_ENABLE) == 0)
 245                         REG_WRITE(map->conf, temp | PIPEACONF_ENABLE);
 246 
 247                 temp = REG_READ(map->status);
 248                 temp &= ~(0xFFFF);
 249                 temp |= PIPE_FIFO_UNDERRUN;
 250                 REG_WRITE(map->status, temp);
 251                 REG_READ(map->status);
 252 
 253                 gma_crtc_load_lut(crtc);
 254 
 255                 /* Give the overlay scaler a chance to enable
 256                  * if it's on this pipe */
 257                 /* psb_intel_crtc_dpms_video(crtc, true); TODO */
 258                 break;
 259         case DRM_MODE_DPMS_OFF:
 260                 if (!gma_crtc->active)
 261                         break;
 262 
 263                 gma_crtc->active = false;
 264 
 265                 /* Give the overlay scaler a chance to disable
 266                  * if it's on this pipe */
 267                 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
 268 
 269                 /* Disable the VGA plane that we never use */
 270                 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
 271 
 272                 /* Turn off vblank interrupts */
 273                 drm_crtc_vblank_off(crtc);
 274 
 275                 /* Wait for vblank for the disable to take effect */
 276                 gma_wait_for_vblank(dev);
 277 
 278                 /* Disable plane */
 279                 temp = REG_READ(map->cntr);
 280                 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
 281                         REG_WRITE(map->cntr,
 282                                   temp & ~DISPLAY_PLANE_ENABLE);
 283                         /* Flush the plane changes */
 284                         REG_WRITE(map->base, REG_READ(map->base));
 285                         REG_READ(map->base);
 286                 }
 287 
 288                 /* Disable pipe */
 289                 temp = REG_READ(map->conf);
 290                 if ((temp & PIPEACONF_ENABLE) != 0) {
 291                         REG_WRITE(map->conf, temp & ~PIPEACONF_ENABLE);
 292                         REG_READ(map->conf);
 293                 }
 294 
 295                 /* Wait for vblank for the disable to take effect. */
 296                 gma_wait_for_vblank(dev);
 297 
 298                 udelay(150);
 299 
 300                 /* Disable DPLL */
 301                 temp = REG_READ(map->dpll);
 302                 if ((temp & DPLL_VCO_ENABLE) != 0) {
 303                         REG_WRITE(map->dpll, temp & ~DPLL_VCO_ENABLE);
 304                         REG_READ(map->dpll);
 305                 }
 306 
 307                 /* Wait for the clocks to turn off. */
 308                 udelay(150);
 309                 break;
 310         }
 311 
 312         if (IS_CDV(dev))
 313                 dev_priv->ops->update_wm(dev, crtc);
 314 
 315         /* Set FIFO watermarks */
 316         REG_WRITE(DSPARB, 0x3F3E);
 317 }
 318 
 319 int gma_crtc_cursor_set(struct drm_crtc *crtc,
 320                         struct drm_file *file_priv,
 321                         uint32_t handle,
 322                         uint32_t width, uint32_t height)
 323 {
 324         struct drm_device *dev = crtc->dev;
 325         struct drm_psb_private *dev_priv = dev->dev_private;
 326         struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
 327         int pipe = gma_crtc->pipe;
 328         uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
 329         uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
 330         uint32_t temp;
 331         size_t addr = 0;
 332         struct gtt_range *gt;
 333         struct gtt_range *cursor_gt = gma_crtc->cursor_gt;
 334         struct drm_gem_object *obj;
 335         void *tmp_dst, *tmp_src;
 336         int ret = 0, i, cursor_pages;
 337 
 338         /* If we didn't get a handle then turn the cursor off */
 339         if (!handle) {
 340                 temp = CURSOR_MODE_DISABLE;
 341                 if (gma_power_begin(dev, false)) {
 342                         REG_WRITE(control, temp);
 343                         REG_WRITE(base, 0);
 344                         gma_power_end(dev);
 345                 }
 346 
 347                 /* Unpin the old GEM object */
 348                 if (gma_crtc->cursor_obj) {
 349                         gt = container_of(gma_crtc->cursor_obj,
 350                                           struct gtt_range, gem);
 351                         psb_gtt_unpin(gt);
 352                         drm_gem_object_put_unlocked(gma_crtc->cursor_obj);
 353                         gma_crtc->cursor_obj = NULL;
 354                 }
 355                 return 0;
 356         }
 357 
 358         /* Currently we only support 64x64 cursors */
 359         if (width != 64 || height != 64) {
 360                 dev_dbg(dev->dev, "We currently only support 64x64 cursors\n");
 361                 return -EINVAL;
 362         }
 363 
 364         obj = drm_gem_object_lookup(file_priv, handle);
 365         if (!obj) {
 366                 ret = -ENOENT;
 367                 goto unlock;
 368         }
 369 
 370         if (obj->size < width * height * 4) {
 371                 dev_dbg(dev->dev, "Buffer is too small\n");
 372                 ret = -ENOMEM;
 373                 goto unref_cursor;
 374         }
 375 
 376         gt = container_of(obj, struct gtt_range, gem);
 377 
 378         /* Pin the memory into the GTT */
 379         ret = psb_gtt_pin(gt);
 380         if (ret) {
 381                 dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
 382                 goto unref_cursor;
 383         }
 384 
 385         if (dev_priv->ops->cursor_needs_phys) {
 386                 if (cursor_gt == NULL) {
 387                         dev_err(dev->dev, "No hardware cursor mem available");
 388                         ret = -ENOMEM;
 389                         goto unref_cursor;
 390                 }
 391 
 392                 /* Prevent overflow */
 393                 if (gt->npage > 4)
 394                         cursor_pages = 4;
 395                 else
 396                         cursor_pages = gt->npage;
 397 
 398                 /* Copy the cursor to cursor mem */
 399                 tmp_dst = dev_priv->vram_addr + cursor_gt->offset;
 400                 for (i = 0; i < cursor_pages; i++) {
 401                         tmp_src = kmap(gt->pages[i]);
 402                         memcpy(tmp_dst, tmp_src, PAGE_SIZE);
 403                         kunmap(gt->pages[i]);
 404                         tmp_dst += PAGE_SIZE;
 405                 }
 406 
 407                 addr = gma_crtc->cursor_addr;
 408         } else {
 409                 addr = gt->offset;
 410                 gma_crtc->cursor_addr = addr;
 411         }
 412 
 413         temp = 0;
 414         /* set the pipe for the cursor */
 415         temp |= (pipe << 28);
 416         temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
 417 
 418         if (gma_power_begin(dev, false)) {
 419                 REG_WRITE(control, temp);
 420                 REG_WRITE(base, addr);
 421                 gma_power_end(dev);
 422         }
 423 
 424         /* unpin the old bo */
 425         if (gma_crtc->cursor_obj) {
 426                 gt = container_of(gma_crtc->cursor_obj, struct gtt_range, gem);
 427                 psb_gtt_unpin(gt);
 428                 drm_gem_object_put_unlocked(gma_crtc->cursor_obj);
 429         }
 430 
 431         gma_crtc->cursor_obj = obj;
 432 unlock:
 433         return ret;
 434 
 435 unref_cursor:
 436         drm_gem_object_put_unlocked(obj);
 437         return ret;
 438 }
 439 
 440 int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 441 {
 442         struct drm_device *dev = crtc->dev;
 443         struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
 444         int pipe = gma_crtc->pipe;
 445         uint32_t temp = 0;
 446         uint32_t addr;
 447 
 448         if (x < 0) {
 449                 temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
 450                 x = -x;
 451         }
 452         if (y < 0) {
 453                 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
 454                 y = -y;
 455         }
 456 
 457         temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
 458         temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
 459 
 460         addr = gma_crtc->cursor_addr;
 461 
 462         if (gma_power_begin(dev, false)) {
 463                 REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
 464                 REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr);
 465                 gma_power_end(dev);
 466         }
 467         return 0;
 468 }
 469 
 470 void gma_crtc_prepare(struct drm_crtc *crtc)
 471 {
 472         const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 473         crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
 474 }
 475 
 476 void gma_crtc_commit(struct drm_crtc *crtc)
 477 {
 478         const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 479         crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
 480 }
 481 
 482 void gma_crtc_disable(struct drm_crtc *crtc)
 483 {
 484         struct gtt_range *gt;
 485         const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 486 
 487         crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
 488 
 489         if (crtc->primary->fb) {
 490                 gt = to_gtt_range(crtc->primary->fb->obj[0]);
 491                 psb_gtt_unpin(gt);
 492         }
 493 }
 494 
 495 void gma_crtc_destroy(struct drm_crtc *crtc)
 496 {
 497         struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
 498 
 499         kfree(gma_crtc->crtc_state);
 500         drm_crtc_cleanup(crtc);
 501         kfree(gma_crtc);
 502 }
 503 
 504 int gma_crtc_set_config(struct drm_mode_set *set,
 505                         struct drm_modeset_acquire_ctx *ctx)
 506 {
 507         struct drm_device *dev = set->crtc->dev;
 508         struct drm_psb_private *dev_priv = dev->dev_private;
 509         int ret;
 510 
 511         if (!dev_priv->rpm_enabled)
 512                 return drm_crtc_helper_set_config(set, ctx);
 513 
 514         pm_runtime_forbid(&dev->pdev->dev);
 515         ret = drm_crtc_helper_set_config(set, ctx);
 516         pm_runtime_allow(&dev->pdev->dev);
 517 
 518         return ret;
 519 }
 520 
 521 /**
 522  * Save HW states of given crtc
 523  */
 524 void gma_crtc_save(struct drm_crtc *crtc)
 525 {
 526         struct drm_device *dev = crtc->dev;
 527         struct drm_psb_private *dev_priv = dev->dev_private;
 528         struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
 529         struct psb_intel_crtc_state *crtc_state = gma_crtc->crtc_state;
 530         const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
 531         uint32_t palette_reg;
 532         int i;
 533 
 534         if (!crtc_state) {
 535                 dev_err(dev->dev, "No CRTC state found\n");
 536                 return;
 537         }
 538 
 539         crtc_state->saveDSPCNTR = REG_READ(map->cntr);
 540         crtc_state->savePIPECONF = REG_READ(map->conf);
 541         crtc_state->savePIPESRC = REG_READ(map->src);
 542         crtc_state->saveFP0 = REG_READ(map->fp0);
 543         crtc_state->saveFP1 = REG_READ(map->fp1);
 544         crtc_state->saveDPLL = REG_READ(map->dpll);
 545         crtc_state->saveHTOTAL = REG_READ(map->htotal);
 546         crtc_state->saveHBLANK = REG_READ(map->hblank);
 547         crtc_state->saveHSYNC = REG_READ(map->hsync);
 548         crtc_state->saveVTOTAL = REG_READ(map->vtotal);
 549         crtc_state->saveVBLANK = REG_READ(map->vblank);
 550         crtc_state->saveVSYNC = REG_READ(map->vsync);
 551         crtc_state->saveDSPSTRIDE = REG_READ(map->stride);
 552 
 553         /* NOTE: DSPSIZE DSPPOS only for psb */
 554         crtc_state->saveDSPSIZE = REG_READ(map->size);
 555         crtc_state->saveDSPPOS = REG_READ(map->pos);
 556 
 557         crtc_state->saveDSPBASE = REG_READ(map->base);
 558 
 559         palette_reg = map->palette;
 560         for (i = 0; i < 256; ++i)
 561                 crtc_state->savePalette[i] = REG_READ(palette_reg + (i << 2));
 562 }
 563 
 564 /**
 565  * Restore HW states of given crtc
 566  */
 567 void gma_crtc_restore(struct drm_crtc *crtc)
 568 {
 569         struct drm_device *dev = crtc->dev;
 570         struct drm_psb_private *dev_priv = dev->dev_private;
 571         struct gma_crtc *gma_crtc =  to_gma_crtc(crtc);
 572         struct psb_intel_crtc_state *crtc_state = gma_crtc->crtc_state;
 573         const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
 574         uint32_t palette_reg;
 575         int i;
 576 
 577         if (!crtc_state) {
 578                 dev_err(dev->dev, "No crtc state\n");
 579                 return;
 580         }
 581 
 582         if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
 583                 REG_WRITE(map->dpll,
 584                         crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
 585                 REG_READ(map->dpll);
 586                 udelay(150);
 587         }
 588 
 589         REG_WRITE(map->fp0, crtc_state->saveFP0);
 590         REG_READ(map->fp0);
 591 
 592         REG_WRITE(map->fp1, crtc_state->saveFP1);
 593         REG_READ(map->fp1);
 594 
 595         REG_WRITE(map->dpll, crtc_state->saveDPLL);
 596         REG_READ(map->dpll);
 597         udelay(150);
 598 
 599         REG_WRITE(map->htotal, crtc_state->saveHTOTAL);
 600         REG_WRITE(map->hblank, crtc_state->saveHBLANK);
 601         REG_WRITE(map->hsync, crtc_state->saveHSYNC);
 602         REG_WRITE(map->vtotal, crtc_state->saveVTOTAL);
 603         REG_WRITE(map->vblank, crtc_state->saveVBLANK);
 604         REG_WRITE(map->vsync, crtc_state->saveVSYNC);
 605         REG_WRITE(map->stride, crtc_state->saveDSPSTRIDE);
 606 
 607         REG_WRITE(map->size, crtc_state->saveDSPSIZE);
 608         REG_WRITE(map->pos, crtc_state->saveDSPPOS);
 609 
 610         REG_WRITE(map->src, crtc_state->savePIPESRC);
 611         REG_WRITE(map->base, crtc_state->saveDSPBASE);
 612         REG_WRITE(map->conf, crtc_state->savePIPECONF);
 613 
 614         gma_wait_for_vblank(dev);
 615 
 616         REG_WRITE(map->cntr, crtc_state->saveDSPCNTR);
 617         REG_WRITE(map->base, crtc_state->saveDSPBASE);
 618 
 619         gma_wait_for_vblank(dev);
 620 
 621         palette_reg = map->palette;
 622         for (i = 0; i < 256; ++i)
 623                 REG_WRITE(palette_reg + (i << 2), crtc_state->savePalette[i]);
 624 }
 625 
 626 void gma_encoder_prepare(struct drm_encoder *encoder)
 627 {
 628         const struct drm_encoder_helper_funcs *encoder_funcs =
 629             encoder->helper_private;
 630         /* lvds has its own version of prepare see psb_intel_lvds_prepare */
 631         encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
 632 }
 633 
 634 void gma_encoder_commit(struct drm_encoder *encoder)
 635 {
 636         const struct drm_encoder_helper_funcs *encoder_funcs =
 637             encoder->helper_private;
 638         /* lvds has its own version of commit see psb_intel_lvds_commit */
 639         encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
 640 }
 641 
 642 void gma_encoder_destroy(struct drm_encoder *encoder)
 643 {
 644         struct gma_encoder *intel_encoder = to_gma_encoder(encoder);
 645 
 646         drm_encoder_cleanup(encoder);
 647         kfree(intel_encoder);
 648 }
 649 
 650 /* Currently there is only a 1:1 mapping of encoders and connectors */
 651 struct drm_encoder *gma_best_encoder(struct drm_connector *connector)
 652 {
 653         struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
 654 
 655         return &gma_encoder->base;
 656 }
 657 
 658 void gma_connector_attach_encoder(struct gma_connector *connector,
 659                                   struct gma_encoder *encoder)
 660 {
 661         connector->encoder = encoder;
 662         drm_connector_attach_encoder(&connector->base,
 663                                           &encoder->base);
 664 }
 665 
 666 #define GMA_PLL_INVALID(s) { /* DRM_ERROR(s); */ return false; }
 667 
 668 bool gma_pll_is_valid(struct drm_crtc *crtc,
 669                       const struct gma_limit_t *limit,
 670                       struct gma_clock_t *clock)
 671 {
 672         if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
 673                 GMA_PLL_INVALID("p1 out of range");
 674         if (clock->p < limit->p.min || limit->p.max < clock->p)
 675                 GMA_PLL_INVALID("p out of range");
 676         if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
 677                 GMA_PLL_INVALID("m2 out of range");
 678         if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
 679                 GMA_PLL_INVALID("m1 out of range");
 680         /* On CDV m1 is always 0 */
 681         if (clock->m1 <= clock->m2 && clock->m1 != 0)
 682                 GMA_PLL_INVALID("m1 <= m2 && m1 != 0");
 683         if (clock->m < limit->m.min || limit->m.max < clock->m)
 684                 GMA_PLL_INVALID("m out of range");
 685         if (clock->n < limit->n.min || limit->n.max < clock->n)
 686                 GMA_PLL_INVALID("n out of range");
 687         if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
 688                 GMA_PLL_INVALID("vco out of range");
 689         /* XXX: We may need to be checking "Dot clock"
 690          * depending on the multiplier, connector, etc.,
 691          * rather than just a single range.
 692          */
 693         if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
 694                 GMA_PLL_INVALID("dot out of range");
 695 
 696         return true;
 697 }
 698 
 699 bool gma_find_best_pll(const struct gma_limit_t *limit,
 700                        struct drm_crtc *crtc, int target, int refclk,
 701                        struct gma_clock_t *best_clock)
 702 {
 703         struct drm_device *dev = crtc->dev;
 704         const struct gma_clock_funcs *clock_funcs =
 705                                                 to_gma_crtc(crtc)->clock_funcs;
 706         struct gma_clock_t clock;
 707         int err = target;
 708 
 709         if (gma_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
 710             (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
 711                 /*
 712                  * For LVDS, if the panel is on, just rely on its current
 713                  * settings for dual-channel.  We haven't figured out how to
 714                  * reliably set up different single/dual channel state, if we
 715                  * even can.
 716                  */
 717                 if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
 718                     LVDS_CLKB_POWER_UP)
 719                         clock.p2 = limit->p2.p2_fast;
 720                 else
 721                         clock.p2 = limit->p2.p2_slow;
 722         } else {
 723                 if (target < limit->p2.dot_limit)
 724                         clock.p2 = limit->p2.p2_slow;
 725                 else
 726                         clock.p2 = limit->p2.p2_fast;
 727         }
 728 
 729         memset(best_clock, 0, sizeof(*best_clock));
 730 
 731         /* m1 is always 0 on CDV so the outmost loop will run just once */
 732         for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
 733                 for (clock.m2 = limit->m2.min;
 734                      (clock.m2 < clock.m1 || clock.m1 == 0) &&
 735                       clock.m2 <= limit->m2.max; clock.m2++) {
 736                         for (clock.n = limit->n.min;
 737                              clock.n <= limit->n.max; clock.n++) {
 738                                 for (clock.p1 = limit->p1.min;
 739                                      clock.p1 <= limit->p1.max;
 740                                      clock.p1++) {
 741                                         int this_err;
 742 
 743                                         clock_funcs->clock(refclk, &clock);
 744 
 745                                         if (!clock_funcs->pll_is_valid(crtc,
 746                                                                 limit, &clock))
 747                                                 continue;
 748 
 749                                         this_err = abs(clock.dot - target);
 750                                         if (this_err < err) {
 751                                                 *best_clock = clock;
 752                                                 err = this_err;
 753                                         }
 754                                 }
 755                         }
 756                 }
 757         }
 758 
 759         return err != target;
 760 }

/* [<][>][^][v][top][bottom][index][help] */