0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/delay.h>
0011 #include <linux/highmem.h>
0012
0013 #include <drm/drm_crtc.h>
0014 #include <drm/drm_fourcc.h>
0015 #include <drm/drm_framebuffer.h>
0016 #include <drm/drm_vblank.h>
0017
0018 #include "framebuffer.h"
0019 #include "gem.h"
0020 #include "gma_display.h"
0021 #include "psb_irq.h"
0022 #include "psb_intel_drv.h"
0023 #include "psb_intel_reg.h"
0024
0025
0026
0027
0028 bool gma_pipe_has_type(struct drm_crtc *crtc, int type)
0029 {
0030 struct drm_device *dev = crtc->dev;
0031 struct drm_connector_list_iter conn_iter;
0032 struct drm_connector *connector;
0033
0034 drm_connector_list_iter_begin(dev, &conn_iter);
0035 drm_for_each_connector_iter(connector, &conn_iter) {
0036 if (connector->encoder && connector->encoder->crtc == crtc) {
0037 struct gma_encoder *gma_encoder =
0038 gma_attached_encoder(connector);
0039 if (gma_encoder->type == type) {
0040 drm_connector_list_iter_end(&conn_iter);
0041 return true;
0042 }
0043 }
0044 }
0045 drm_connector_list_iter_end(&conn_iter);
0046
0047 return false;
0048 }
0049
0050 void gma_wait_for_vblank(struct drm_device *dev)
0051 {
0052
0053 mdelay(20);
0054 }
0055
0056 int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y,
0057 struct drm_framebuffer *old_fb)
0058 {
0059 struct drm_device *dev = crtc->dev;
0060 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0061 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
0062 struct drm_framebuffer *fb = crtc->primary->fb;
0063 struct psb_gem_object *pobj;
0064 int pipe = gma_crtc->pipe;
0065 const struct psb_offset *map = &dev_priv->regmap[pipe];
0066 unsigned long start, offset;
0067 u32 dspcntr;
0068 int ret = 0;
0069
0070 if (!gma_power_begin(dev, true))
0071 return 0;
0072
0073
0074 if (!fb) {
0075 dev_err(dev->dev, "No FB bound\n");
0076 goto gma_pipe_cleaner;
0077 }
0078
0079 pobj = to_psb_gem_object(fb->obj[0]);
0080
0081
0082
0083 ret = psb_gem_pin(pobj);
0084 if (ret < 0)
0085 goto gma_pipe_set_base_exit;
0086 start = pobj->offset;
0087 offset = y * fb->pitches[0] + x * fb->format->cpp[0];
0088
0089 REG_WRITE(map->stride, fb->pitches[0]);
0090
0091 dspcntr = REG_READ(map->cntr);
0092 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
0093
0094 switch (fb->format->cpp[0] * 8) {
0095 case 8:
0096 dspcntr |= DISPPLANE_8BPP;
0097 break;
0098 case 16:
0099 if (fb->format->depth == 15)
0100 dspcntr |= DISPPLANE_15_16BPP;
0101 else
0102 dspcntr |= DISPPLANE_16BPP;
0103 break;
0104 case 24:
0105 case 32:
0106 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
0107 break;
0108 default:
0109 dev_err(dev->dev, "Unknown color depth\n");
0110 ret = -EINVAL;
0111 goto gma_pipe_set_base_exit;
0112 }
0113 REG_WRITE(map->cntr, dspcntr);
0114
0115 dev_dbg(dev->dev,
0116 "Writing base %08lX %08lX %d %d\n", start, offset, x, y);
0117
0118
0119
0120
0121 if (IS_PSB(dev)) {
0122 REG_WRITE(map->base, offset + start);
0123 REG_READ(map->base);
0124 } else {
0125 REG_WRITE(map->base, offset);
0126 REG_READ(map->base);
0127 REG_WRITE(map->surf, start);
0128 REG_READ(map->surf);
0129 }
0130
0131 gma_pipe_cleaner:
0132
0133 if (old_fb)
0134 psb_gem_unpin(to_psb_gem_object(old_fb->obj[0]));
0135
0136 gma_pipe_set_base_exit:
0137 gma_power_end(dev);
0138 return ret;
0139 }
0140
0141
0142 void gma_crtc_load_lut(struct drm_crtc *crtc)
0143 {
0144 struct drm_device *dev = crtc->dev;
0145 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0146 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
0147 const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
0148 int palreg = map->palette;
0149 u16 *r, *g, *b;
0150 int i;
0151
0152
0153 if (!crtc->enabled)
0154 return;
0155
0156 r = crtc->gamma_store;
0157 g = r + crtc->gamma_size;
0158 b = g + crtc->gamma_size;
0159
0160 if (gma_power_begin(dev, false)) {
0161 for (i = 0; i < 256; i++) {
0162 REG_WRITE(palreg + 4 * i,
0163 (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
0164 (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
0165 ((*b++ >> 8) + gma_crtc->lut_adj[i]));
0166 }
0167 gma_power_end(dev);
0168 } else {
0169 for (i = 0; i < 256; i++) {
0170
0171 dev_priv->regs.pipe[0].palette[i] =
0172 (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
0173 (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
0174 ((*b++ >> 8) + gma_crtc->lut_adj[i]);
0175 }
0176
0177 }
0178 }
0179
0180 static int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
0181 u16 *blue, u32 size,
0182 struct drm_modeset_acquire_ctx *ctx)
0183 {
0184 gma_crtc_load_lut(crtc);
0185
0186 return 0;
0187 }
0188
0189
0190
0191
0192
0193
0194
0195 void gma_crtc_dpms(struct drm_crtc *crtc, int mode)
0196 {
0197 struct drm_device *dev = crtc->dev;
0198 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0199 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
0200 int pipe = gma_crtc->pipe;
0201 const struct psb_offset *map = &dev_priv->regmap[pipe];
0202 u32 temp;
0203
0204
0205
0206
0207
0208 if (IS_CDV(dev))
0209 dev_priv->ops->disable_sr(dev);
0210
0211 switch (mode) {
0212 case DRM_MODE_DPMS_ON:
0213 case DRM_MODE_DPMS_STANDBY:
0214 case DRM_MODE_DPMS_SUSPEND:
0215 if (gma_crtc->active)
0216 break;
0217
0218 gma_crtc->active = true;
0219
0220
0221 temp = REG_READ(map->dpll);
0222 if ((temp & DPLL_VCO_ENABLE) == 0) {
0223 REG_WRITE(map->dpll, temp);
0224 REG_READ(map->dpll);
0225
0226 udelay(150);
0227 REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE);
0228 REG_READ(map->dpll);
0229
0230 udelay(150);
0231 REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE);
0232 REG_READ(map->dpll);
0233
0234 udelay(150);
0235 }
0236
0237
0238 temp = REG_READ(map->cntr);
0239 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
0240 REG_WRITE(map->cntr,
0241 temp | DISPLAY_PLANE_ENABLE);
0242
0243 REG_WRITE(map->base, REG_READ(map->base));
0244 }
0245
0246 udelay(150);
0247
0248
0249 temp = REG_READ(map->conf);
0250 if ((temp & PIPEACONF_ENABLE) == 0)
0251 REG_WRITE(map->conf, temp | PIPEACONF_ENABLE);
0252
0253 temp = REG_READ(map->status);
0254 temp &= ~(0xFFFF);
0255 temp |= PIPE_FIFO_UNDERRUN;
0256 REG_WRITE(map->status, temp);
0257 REG_READ(map->status);
0258
0259 gma_crtc_load_lut(crtc);
0260
0261
0262
0263
0264
0265 drm_crtc_vblank_on(crtc);
0266 break;
0267 case DRM_MODE_DPMS_OFF:
0268 if (!gma_crtc->active)
0269 break;
0270
0271 gma_crtc->active = false;
0272
0273
0274
0275
0276
0277
0278 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
0279
0280
0281 drm_crtc_vblank_off(crtc);
0282
0283
0284 gma_wait_for_vblank(dev);
0285
0286
0287 temp = REG_READ(map->cntr);
0288 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
0289 REG_WRITE(map->cntr,
0290 temp & ~DISPLAY_PLANE_ENABLE);
0291
0292 REG_WRITE(map->base, REG_READ(map->base));
0293 REG_READ(map->base);
0294 }
0295
0296
0297 temp = REG_READ(map->conf);
0298 if ((temp & PIPEACONF_ENABLE) != 0) {
0299 REG_WRITE(map->conf, temp & ~PIPEACONF_ENABLE);
0300 REG_READ(map->conf);
0301 }
0302
0303
0304 gma_wait_for_vblank(dev);
0305
0306 udelay(150);
0307
0308
0309 temp = REG_READ(map->dpll);
0310 if ((temp & DPLL_VCO_ENABLE) != 0) {
0311 REG_WRITE(map->dpll, temp & ~DPLL_VCO_ENABLE);
0312 REG_READ(map->dpll);
0313 }
0314
0315
0316 udelay(150);
0317 break;
0318 }
0319
0320 if (IS_CDV(dev))
0321 dev_priv->ops->update_wm(dev, crtc);
0322
0323
0324 REG_WRITE(DSPARB, 0x3F3E);
0325 }
0326
0327 static int gma_crtc_cursor_set(struct drm_crtc *crtc,
0328 struct drm_file *file_priv, uint32_t handle,
0329 uint32_t width, uint32_t height)
0330 {
0331 struct drm_device *dev = crtc->dev;
0332 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0333 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
0334 int pipe = gma_crtc->pipe;
0335 uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
0336 uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
0337 uint32_t temp;
0338 size_t addr = 0;
0339 struct psb_gem_object *pobj;
0340 struct psb_gem_object *cursor_pobj = gma_crtc->cursor_pobj;
0341 struct drm_gem_object *obj;
0342 void *tmp_dst;
0343 int ret = 0, i, cursor_pages;
0344
0345
0346 if (!handle) {
0347 temp = CURSOR_MODE_DISABLE;
0348 if (gma_power_begin(dev, false)) {
0349 REG_WRITE(control, temp);
0350 REG_WRITE(base, 0);
0351 gma_power_end(dev);
0352 }
0353
0354
0355 if (gma_crtc->cursor_obj) {
0356 pobj = to_psb_gem_object(gma_crtc->cursor_obj);
0357 psb_gem_unpin(pobj);
0358 drm_gem_object_put(gma_crtc->cursor_obj);
0359 gma_crtc->cursor_obj = NULL;
0360 }
0361 return 0;
0362 }
0363
0364
0365 if (width != 64 || height != 64) {
0366 dev_dbg(dev->dev, "We currently only support 64x64 cursors\n");
0367 return -EINVAL;
0368 }
0369
0370 obj = drm_gem_object_lookup(file_priv, handle);
0371 if (!obj) {
0372 ret = -ENOENT;
0373 goto unlock;
0374 }
0375
0376 if (obj->size < width * height * 4) {
0377 dev_dbg(dev->dev, "Buffer is too small\n");
0378 ret = -ENOMEM;
0379 goto unref_cursor;
0380 }
0381
0382 pobj = to_psb_gem_object(obj);
0383
0384
0385 ret = psb_gem_pin(pobj);
0386 if (ret) {
0387 dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
0388 goto unref_cursor;
0389 }
0390
0391 if (dev_priv->ops->cursor_needs_phys) {
0392 if (!cursor_pobj) {
0393 dev_err(dev->dev, "No hardware cursor mem available");
0394 ret = -ENOMEM;
0395 goto unref_cursor;
0396 }
0397
0398 cursor_pages = obj->size / PAGE_SIZE;
0399 if (cursor_pages > 4)
0400 cursor_pages = 4;
0401
0402
0403 tmp_dst = dev_priv->vram_addr + cursor_pobj->offset;
0404 for (i = 0; i < cursor_pages; i++) {
0405 memcpy_from_page(tmp_dst, pobj->pages[i], 0, PAGE_SIZE);
0406 tmp_dst += PAGE_SIZE;
0407 }
0408
0409 addr = gma_crtc->cursor_addr;
0410 } else {
0411 addr = pobj->offset;
0412 gma_crtc->cursor_addr = addr;
0413 }
0414
0415 temp = 0;
0416
0417 temp |= (pipe << 28);
0418 temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
0419
0420 if (gma_power_begin(dev, false)) {
0421 REG_WRITE(control, temp);
0422 REG_WRITE(base, addr);
0423 gma_power_end(dev);
0424 }
0425
0426
0427 if (gma_crtc->cursor_obj) {
0428 pobj = to_psb_gem_object(gma_crtc->cursor_obj);
0429 psb_gem_unpin(pobj);
0430 drm_gem_object_put(gma_crtc->cursor_obj);
0431 }
0432
0433 gma_crtc->cursor_obj = obj;
0434 unlock:
0435 return ret;
0436
0437 unref_cursor:
0438 drm_gem_object_put(obj);
0439 return ret;
0440 }
0441
0442 static int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
0443 {
0444 struct drm_device *dev = crtc->dev;
0445 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
0446 int pipe = gma_crtc->pipe;
0447 uint32_t temp = 0;
0448 uint32_t addr;
0449
0450 if (x < 0) {
0451 temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
0452 x = -x;
0453 }
0454 if (y < 0) {
0455 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
0456 y = -y;
0457 }
0458
0459 temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
0460 temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
0461
0462 addr = gma_crtc->cursor_addr;
0463
0464 if (gma_power_begin(dev, false)) {
0465 REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
0466 REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr);
0467 gma_power_end(dev);
0468 }
0469 return 0;
0470 }
0471
0472 void gma_crtc_prepare(struct drm_crtc *crtc)
0473 {
0474 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0475 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
0476 }
0477
0478 void gma_crtc_commit(struct drm_crtc *crtc)
0479 {
0480 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0481 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
0482 }
0483
0484 void gma_crtc_disable(struct drm_crtc *crtc)
0485 {
0486 struct psb_gem_object *pobj;
0487 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0488
0489 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
0490
0491 if (crtc->primary->fb) {
0492 pobj = to_psb_gem_object(crtc->primary->fb->obj[0]);
0493 psb_gem_unpin(pobj);
0494 }
0495 }
0496
0497 void gma_crtc_destroy(struct drm_crtc *crtc)
0498 {
0499 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
0500
0501 if (gma_crtc->cursor_pobj)
0502 drm_gem_object_put(&gma_crtc->cursor_pobj->base);
0503
0504 kfree(gma_crtc->crtc_state);
0505 drm_crtc_cleanup(crtc);
0506 kfree(gma_crtc);
0507 }
0508
0509 int gma_crtc_page_flip(struct drm_crtc *crtc,
0510 struct drm_framebuffer *fb,
0511 struct drm_pending_vblank_event *event,
0512 uint32_t page_flip_flags,
0513 struct drm_modeset_acquire_ctx *ctx)
0514 {
0515 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
0516 struct drm_framebuffer *current_fb = crtc->primary->fb;
0517 struct drm_framebuffer *old_fb = crtc->primary->old_fb;
0518 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0519 struct drm_device *dev = crtc->dev;
0520 unsigned long flags;
0521 int ret;
0522
0523 if (!crtc_funcs->mode_set_base)
0524 return -EINVAL;
0525
0526
0527 crtc->primary->fb = fb;
0528
0529 if (event) {
0530 spin_lock_irqsave(&dev->event_lock, flags);
0531
0532 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
0533
0534 gma_crtc->page_flip_event = event;
0535 spin_unlock_irqrestore(&dev->event_lock, flags);
0536
0537
0538 ret = crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, old_fb);
0539 if (ret) {
0540 spin_lock_irqsave(&dev->event_lock, flags);
0541 if (gma_crtc->page_flip_event) {
0542 gma_crtc->page_flip_event = NULL;
0543 drm_crtc_vblank_put(crtc);
0544 }
0545 spin_unlock_irqrestore(&dev->event_lock, flags);
0546 }
0547 } else {
0548 ret = crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, old_fb);
0549 }
0550
0551
0552 if (ret)
0553 crtc->primary->fb = current_fb;
0554
0555 return ret;
0556 }
0557
0558 int gma_crtc_set_config(struct drm_mode_set *set,
0559 struct drm_modeset_acquire_ctx *ctx)
0560 {
0561 struct drm_device *dev = set->crtc->dev;
0562 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0563 int ret;
0564
0565 if (!dev_priv->rpm_enabled)
0566 return drm_crtc_helper_set_config(set, ctx);
0567
0568 pm_runtime_forbid(dev->dev);
0569 ret = drm_crtc_helper_set_config(set, ctx);
0570 pm_runtime_allow(dev->dev);
0571
0572 return ret;
0573 }
0574
0575 const struct drm_crtc_funcs gma_crtc_funcs = {
0576 .cursor_set = gma_crtc_cursor_set,
0577 .cursor_move = gma_crtc_cursor_move,
0578 .gamma_set = gma_crtc_gamma_set,
0579 .set_config = gma_crtc_set_config,
0580 .destroy = gma_crtc_destroy,
0581 .page_flip = gma_crtc_page_flip,
0582 .enable_vblank = gma_crtc_enable_vblank,
0583 .disable_vblank = gma_crtc_disable_vblank,
0584 .get_vblank_counter = gma_crtc_get_vblank_counter,
0585 };
0586
0587
0588
0589
0590 void gma_crtc_save(struct drm_crtc *crtc)
0591 {
0592 struct drm_device *dev = crtc->dev;
0593 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0594 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
0595 struct psb_intel_crtc_state *crtc_state = gma_crtc->crtc_state;
0596 const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
0597 uint32_t palette_reg;
0598 int i;
0599
0600 if (!crtc_state) {
0601 dev_err(dev->dev, "No CRTC state found\n");
0602 return;
0603 }
0604
0605 crtc_state->saveDSPCNTR = REG_READ(map->cntr);
0606 crtc_state->savePIPECONF = REG_READ(map->conf);
0607 crtc_state->savePIPESRC = REG_READ(map->src);
0608 crtc_state->saveFP0 = REG_READ(map->fp0);
0609 crtc_state->saveFP1 = REG_READ(map->fp1);
0610 crtc_state->saveDPLL = REG_READ(map->dpll);
0611 crtc_state->saveHTOTAL = REG_READ(map->htotal);
0612 crtc_state->saveHBLANK = REG_READ(map->hblank);
0613 crtc_state->saveHSYNC = REG_READ(map->hsync);
0614 crtc_state->saveVTOTAL = REG_READ(map->vtotal);
0615 crtc_state->saveVBLANK = REG_READ(map->vblank);
0616 crtc_state->saveVSYNC = REG_READ(map->vsync);
0617 crtc_state->saveDSPSTRIDE = REG_READ(map->stride);
0618
0619
0620 crtc_state->saveDSPSIZE = REG_READ(map->size);
0621 crtc_state->saveDSPPOS = REG_READ(map->pos);
0622
0623 crtc_state->saveDSPBASE = REG_READ(map->base);
0624
0625 palette_reg = map->palette;
0626 for (i = 0; i < 256; ++i)
0627 crtc_state->savePalette[i] = REG_READ(palette_reg + (i << 2));
0628 }
0629
0630
0631
0632
0633 void gma_crtc_restore(struct drm_crtc *crtc)
0634 {
0635 struct drm_device *dev = crtc->dev;
0636 struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
0637 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
0638 struct psb_intel_crtc_state *crtc_state = gma_crtc->crtc_state;
0639 const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
0640 uint32_t palette_reg;
0641 int i;
0642
0643 if (!crtc_state) {
0644 dev_err(dev->dev, "No crtc state\n");
0645 return;
0646 }
0647
0648 if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
0649 REG_WRITE(map->dpll,
0650 crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
0651 REG_READ(map->dpll);
0652 udelay(150);
0653 }
0654
0655 REG_WRITE(map->fp0, crtc_state->saveFP0);
0656 REG_READ(map->fp0);
0657
0658 REG_WRITE(map->fp1, crtc_state->saveFP1);
0659 REG_READ(map->fp1);
0660
0661 REG_WRITE(map->dpll, crtc_state->saveDPLL);
0662 REG_READ(map->dpll);
0663 udelay(150);
0664
0665 REG_WRITE(map->htotal, crtc_state->saveHTOTAL);
0666 REG_WRITE(map->hblank, crtc_state->saveHBLANK);
0667 REG_WRITE(map->hsync, crtc_state->saveHSYNC);
0668 REG_WRITE(map->vtotal, crtc_state->saveVTOTAL);
0669 REG_WRITE(map->vblank, crtc_state->saveVBLANK);
0670 REG_WRITE(map->vsync, crtc_state->saveVSYNC);
0671 REG_WRITE(map->stride, crtc_state->saveDSPSTRIDE);
0672
0673 REG_WRITE(map->size, crtc_state->saveDSPSIZE);
0674 REG_WRITE(map->pos, crtc_state->saveDSPPOS);
0675
0676 REG_WRITE(map->src, crtc_state->savePIPESRC);
0677 REG_WRITE(map->base, crtc_state->saveDSPBASE);
0678 REG_WRITE(map->conf, crtc_state->savePIPECONF);
0679
0680 gma_wait_for_vblank(dev);
0681
0682 REG_WRITE(map->cntr, crtc_state->saveDSPCNTR);
0683 REG_WRITE(map->base, crtc_state->saveDSPBASE);
0684
0685 gma_wait_for_vblank(dev);
0686
0687 palette_reg = map->palette;
0688 for (i = 0; i < 256; ++i)
0689 REG_WRITE(palette_reg + (i << 2), crtc_state->savePalette[i]);
0690 }
0691
0692 void gma_encoder_prepare(struct drm_encoder *encoder)
0693 {
0694 const struct drm_encoder_helper_funcs *encoder_funcs =
0695 encoder->helper_private;
0696
0697 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
0698 }
0699
0700 void gma_encoder_commit(struct drm_encoder *encoder)
0701 {
0702 const struct drm_encoder_helper_funcs *encoder_funcs =
0703 encoder->helper_private;
0704
0705 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
0706 }
0707
0708 void gma_encoder_destroy(struct drm_encoder *encoder)
0709 {
0710 struct gma_encoder *intel_encoder = to_gma_encoder(encoder);
0711
0712 drm_encoder_cleanup(encoder);
0713 kfree(intel_encoder);
0714 }
0715
0716
0717 struct drm_encoder *gma_best_encoder(struct drm_connector *connector)
0718 {
0719 struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
0720
0721 return &gma_encoder->base;
0722 }
0723
0724 void gma_connector_attach_encoder(struct gma_connector *connector,
0725 struct gma_encoder *encoder)
0726 {
0727 connector->encoder = encoder;
0728 drm_connector_attach_encoder(&connector->base,
0729 &encoder->base);
0730 }
0731
0732 #define GMA_PLL_INVALID(s) { return false; }
0733
0734 bool gma_pll_is_valid(struct drm_crtc *crtc,
0735 const struct gma_limit_t *limit,
0736 struct gma_clock_t *clock)
0737 {
0738 if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
0739 GMA_PLL_INVALID("p1 out of range");
0740 if (clock->p < limit->p.min || limit->p.max < clock->p)
0741 GMA_PLL_INVALID("p out of range");
0742 if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
0743 GMA_PLL_INVALID("m2 out of range");
0744 if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
0745 GMA_PLL_INVALID("m1 out of range");
0746
0747 if (clock->m1 <= clock->m2 && clock->m1 != 0)
0748 GMA_PLL_INVALID("m1 <= m2 && m1 != 0");
0749 if (clock->m < limit->m.min || limit->m.max < clock->m)
0750 GMA_PLL_INVALID("m out of range");
0751 if (clock->n < limit->n.min || limit->n.max < clock->n)
0752 GMA_PLL_INVALID("n out of range");
0753 if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
0754 GMA_PLL_INVALID("vco out of range");
0755
0756
0757
0758
0759 if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
0760 GMA_PLL_INVALID("dot out of range");
0761
0762 return true;
0763 }
0764
0765 bool gma_find_best_pll(const struct gma_limit_t *limit,
0766 struct drm_crtc *crtc, int target, int refclk,
0767 struct gma_clock_t *best_clock)
0768 {
0769 struct drm_device *dev = crtc->dev;
0770 const struct gma_clock_funcs *clock_funcs =
0771 to_gma_crtc(crtc)->clock_funcs;
0772 struct gma_clock_t clock;
0773 int err = target;
0774
0775 if (gma_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
0776 (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
0777
0778
0779
0780
0781
0782
0783 if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
0784 LVDS_CLKB_POWER_UP)
0785 clock.p2 = limit->p2.p2_fast;
0786 else
0787 clock.p2 = limit->p2.p2_slow;
0788 } else {
0789 if (target < limit->p2.dot_limit)
0790 clock.p2 = limit->p2.p2_slow;
0791 else
0792 clock.p2 = limit->p2.p2_fast;
0793 }
0794
0795 memset(best_clock, 0, sizeof(*best_clock));
0796
0797
0798 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
0799 for (clock.m2 = limit->m2.min;
0800 (clock.m2 < clock.m1 || clock.m1 == 0) &&
0801 clock.m2 <= limit->m2.max; clock.m2++) {
0802 for (clock.n = limit->n.min;
0803 clock.n <= limit->n.max; clock.n++) {
0804 for (clock.p1 = limit->p1.min;
0805 clock.p1 <= limit->p1.max;
0806 clock.p1++) {
0807 int this_err;
0808
0809 clock_funcs->clock(refclk, &clock);
0810
0811 if (!clock_funcs->pll_is_valid(crtc,
0812 limit, &clock))
0813 continue;
0814
0815 this_err = abs(clock.dot - target);
0816 if (this_err < err) {
0817 *best_clock = clock;
0818 err = this_err;
0819 }
0820 }
0821 }
0822 }
0823 }
0824
0825 return err != target;
0826 }