1/* 2 * Copyright © 2006-2007 Intel Corporation 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program; if not, write to the Free Software Foundation, Inc., 15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 * 17 * Authors: 18 * Eric Anholt <eric@anholt.net> 19 */ 20 21#include <linux/i2c.h> 22#include <linux/pm_runtime.h> 23 24#include <drm/drmP.h> 25#include "psb_intel_reg.h" 26#include "gma_display.h" 27#include "framebuffer.h" 28#include "mdfld_output.h" 29#include "mdfld_dsi_output.h" 30 31/* Hardcoded currently */ 32static int ksel = KSEL_CRYSTAL_19; 33 34struct psb_intel_range_t { 35 int min, max; 36}; 37 38struct mrst_limit_t { 39 struct psb_intel_range_t dot, m, p1; 40}; 41 42struct mrst_clock_t { 43 /* derived values */ 44 int dot; 45 int m; 46 int p1; 47}; 48 49#define COUNT_MAX 0x10000000 50 51void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe) 52{ 53 struct drm_psb_private *dev_priv = dev->dev_private; 54 const struct psb_offset *map = &dev_priv->regmap[pipe]; 55 int count, temp; 56 57 switch (pipe) { 58 case 0: 59 case 1: 60 case 2: 61 break; 62 default: 63 DRM_ERROR("Illegal Pipe Number.\n"); 64 return; 65 } 66 67 /* FIXME JLIU7_PO */ 68 gma_wait_for_vblank(dev); 69 return; 70 71 /* Wait for for the pipe disable to take effect. */ 72 for (count = 0; count < COUNT_MAX; count++) { 73 temp = REG_READ(map->conf); 74 if ((temp & PIPEACONF_PIPE_STATE) == 0) 75 break; 76 } 77} 78 79void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe) 80{ 81 struct drm_psb_private *dev_priv = dev->dev_private; 82 const struct psb_offset *map = &dev_priv->regmap[pipe]; 83 int count, temp; 84 85 switch (pipe) { 86 case 0: 87 case 1: 88 case 2: 89 break; 90 default: 91 DRM_ERROR("Illegal Pipe Number.\n"); 92 return; 93 } 94 95 /* FIXME JLIU7_PO */ 96 gma_wait_for_vblank(dev); 97 return; 98 99 /* Wait for for the pipe enable to take effect. */ 100 for (count = 0; count < COUNT_MAX; count++) { 101 temp = REG_READ(map->conf); 102 if ((temp & PIPEACONF_PIPE_STATE) == 1) 103 break; 104 } 105} 106 107/** 108 * Return the pipe currently connected to the panel fitter, 109 * or -1 if the panel fitter is not present or not in use 110 */ 111static int psb_intel_panel_fitter_pipe(struct drm_device *dev) 112{ 113 u32 pfit_control; 114 115 pfit_control = REG_READ(PFIT_CONTROL); 116 117 /* See if the panel fitter is in use */ 118 if ((pfit_control & PFIT_ENABLE) == 0) 119 return -1; 120 121 /* 965 can place panel fitter on either pipe */ 122 return (pfit_control >> 29) & 0x3; 123} 124 125static struct drm_device globle_dev; 126 127void mdfld__intel_plane_set_alpha(int enable) 128{ 129 struct drm_device *dev = &globle_dev; 130 int dspcntr_reg = DSPACNTR; 131 u32 dspcntr; 132 133 dspcntr = REG_READ(dspcntr_reg); 134 135 if (enable) { 136 dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA; 137 dspcntr |= DISPPLANE_32BPP; 138 } else { 139 dspcntr &= ~DISPPLANE_32BPP; 140 dspcntr |= DISPPLANE_32BPP_NO_ALPHA; 141 } 142 143 REG_WRITE(dspcntr_reg, dspcntr); 144} 145 146static int check_fb(struct drm_framebuffer *fb) 147{ 148 if (!fb) 149 return 0; 150 151 switch (fb->bits_per_pixel) { 152 case 8: 153 case 16: 154 case 24: 155 case 32: 156 return 0; 157 default: 158 DRM_ERROR("Unknown color depth\n"); 159 return -EINVAL; 160 } 161} 162 163static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, 164 struct drm_framebuffer *old_fb) 165{ 166 struct drm_device *dev = crtc->dev; 167 struct drm_psb_private *dev_priv = dev->dev_private; 168 struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 169 struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb); 170 int pipe = gma_crtc->pipe; 171 const struct psb_offset *map = &dev_priv->regmap[pipe]; 172 unsigned long start, offset; 173 u32 dspcntr; 174 int ret; 175 176 memcpy(&globle_dev, dev, sizeof(struct drm_device)); 177 178 dev_dbg(dev->dev, "pipe = 0x%x.\n", pipe); 179 180 /* no fb bound */ 181 if (!crtc->primary->fb) { 182 dev_dbg(dev->dev, "No FB bound\n"); 183 return 0; 184 } 185 186 ret = check_fb(crtc->primary->fb); 187 if (ret) 188 return ret; 189 190 if (pipe > 2) { 191 DRM_ERROR("Illegal Pipe Number.\n"); 192 return -EINVAL; 193 } 194 195 if (!gma_power_begin(dev, true)) 196 return 0; 197 198 start = psbfb->gtt->offset; 199 offset = y * crtc->primary->fb->pitches[0] + x * (crtc->primary->fb->bits_per_pixel / 8); 200 201 REG_WRITE(map->stride, crtc->primary->fb->pitches[0]); 202 dspcntr = REG_READ(map->cntr); 203 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; 204 205 switch (crtc->primary->fb->bits_per_pixel) { 206 case 8: 207 dspcntr |= DISPPLANE_8BPP; 208 break; 209 case 16: 210 if (crtc->primary->fb->depth == 15) 211 dspcntr |= DISPPLANE_15_16BPP; 212 else 213 dspcntr |= DISPPLANE_16BPP; 214 break; 215 case 24: 216 case 32: 217 dspcntr |= DISPPLANE_32BPP_NO_ALPHA; 218 break; 219 } 220 REG_WRITE(map->cntr, dspcntr); 221 222 dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n", 223 start, offset, x, y); 224 REG_WRITE(map->linoff, offset); 225 REG_READ(map->linoff); 226 REG_WRITE(map->surf, start); 227 REG_READ(map->surf); 228 229 gma_power_end(dev); 230 231 return 0; 232} 233 234/* 235 * Disable the pipe, plane and pll. 236 * 237 */ 238void mdfld_disable_crtc(struct drm_device *dev, int pipe) 239{ 240 struct drm_psb_private *dev_priv = dev->dev_private; 241 const struct psb_offset *map = &dev_priv->regmap[pipe]; 242 u32 temp; 243 244 dev_dbg(dev->dev, "pipe = %d\n", pipe); 245 246 247 if (pipe != 1) 248 mdfld_dsi_gen_fifo_ready(dev, MIPI_GEN_FIFO_STAT_REG(pipe), 249 HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); 250 251 /* Disable display plane */ 252 temp = REG_READ(map->cntr); 253 if ((temp & DISPLAY_PLANE_ENABLE) != 0) { 254 REG_WRITE(map->cntr, 255 temp & ~DISPLAY_PLANE_ENABLE); 256 /* Flush the plane changes */ 257 REG_WRITE(map->base, REG_READ(map->base)); 258 REG_READ(map->base); 259 } 260 261 /* FIXME_JLIU7 MDFLD_PO revisit */ 262 263 /* Next, disable display pipes */ 264 temp = REG_READ(map->conf); 265 if ((temp & PIPEACONF_ENABLE) != 0) { 266 temp &= ~PIPEACONF_ENABLE; 267 temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; 268 REG_WRITE(map->conf, temp); 269 REG_READ(map->conf); 270 271 /* Wait for for the pipe disable to take effect. */ 272 mdfldWaitForPipeDisable(dev, pipe); 273 } 274 275 temp = REG_READ(map->dpll); 276 if (temp & DPLL_VCO_ENABLE) { 277 if ((pipe != 1 && 278 !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) 279 & PIPEACONF_ENABLE)) || pipe == 1) { 280 temp &= ~(DPLL_VCO_ENABLE); 281 REG_WRITE(map->dpll, temp); 282 REG_READ(map->dpll); 283 /* Wait for the clocks to turn off. */ 284 /* FIXME_MDFLD PO may need more delay */ 285 udelay(500); 286 287 if (!(temp & MDFLD_PWR_GATE_EN)) { 288 /* gating power of DPLL */ 289 REG_WRITE(map->dpll, temp | MDFLD_PWR_GATE_EN); 290 /* FIXME_MDFLD PO - change 500 to 1 after PO */ 291 udelay(5000); 292 } 293 } 294 } 295 296} 297 298/** 299 * Sets the power management mode of the pipe and plane. 300 * 301 * This code should probably grow support for turning the cursor off and back 302 * on appropriately at the same time as we're turning the pipe off/on. 303 */ 304static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) 305{ 306 struct drm_device *dev = crtc->dev; 307 struct drm_psb_private *dev_priv = dev->dev_private; 308 struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 309 int pipe = gma_crtc->pipe; 310 const struct psb_offset *map = &dev_priv->regmap[pipe]; 311 u32 pipeconf = dev_priv->pipeconf[pipe]; 312 u32 temp; 313 int timeout = 0; 314 315 dev_dbg(dev->dev, "mode = %d, pipe = %d\n", mode, pipe); 316 317 /* Note: Old code uses pipe a stat for pipe b but that appears 318 to be a bug */ 319 320 if (!gma_power_begin(dev, true)) 321 return; 322 323 /* XXX: When our outputs are all unaware of DPMS modes other than off 324 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. 325 */ 326 switch (mode) { 327 case DRM_MODE_DPMS_ON: 328 case DRM_MODE_DPMS_STANDBY: 329 case DRM_MODE_DPMS_SUSPEND: 330 /* Enable the DPLL */ 331 temp = REG_READ(map->dpll); 332 333 if ((temp & DPLL_VCO_ENABLE) == 0) { 334 /* When ungating power of DPLL, needs to wait 0.5us 335 before enable the VCO */ 336 if (temp & MDFLD_PWR_GATE_EN) { 337 temp &= ~MDFLD_PWR_GATE_EN; 338 REG_WRITE(map->dpll, temp); 339 /* FIXME_MDFLD PO - change 500 to 1 after PO */ 340 udelay(500); 341 } 342 343 REG_WRITE(map->dpll, temp); 344 REG_READ(map->dpll); 345 /* FIXME_MDFLD PO - change 500 to 1 after PO */ 346 udelay(500); 347 348 REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); 349 REG_READ(map->dpll); 350 351 /** 352 * wait for DSI PLL to lock 353 * NOTE: only need to poll status of pipe 0 and pipe 1, 354 * since both MIPI pipes share the same PLL. 355 */ 356 while ((pipe != 2) && (timeout < 20000) && 357 !(REG_READ(map->conf) & PIPECONF_DSIPLL_LOCK)) { 358 udelay(150); 359 timeout++; 360 } 361 } 362 363 /* Enable the plane */ 364 temp = REG_READ(map->cntr); 365 if ((temp & DISPLAY_PLANE_ENABLE) == 0) { 366 REG_WRITE(map->cntr, 367 temp | DISPLAY_PLANE_ENABLE); 368 /* Flush the plane changes */ 369 REG_WRITE(map->base, REG_READ(map->base)); 370 } 371 372 /* Enable the pipe */ 373 temp = REG_READ(map->conf); 374 if ((temp & PIPEACONF_ENABLE) == 0) { 375 REG_WRITE(map->conf, pipeconf); 376 377 /* Wait for for the pipe enable to take effect. */ 378 mdfldWaitForPipeEnable(dev, pipe); 379 } 380 381 /*workaround for sighting 3741701 Random X blank display*/ 382 /*perform w/a in video mode only on pipe A or C*/ 383 if (pipe == 0 || pipe == 2) { 384 REG_WRITE(map->status, REG_READ(map->status)); 385 msleep(100); 386 if (PIPE_VBLANK_STATUS & REG_READ(map->status)) 387 dev_dbg(dev->dev, "OK"); 388 else { 389 dev_dbg(dev->dev, "STUCK!!!!"); 390 /*shutdown controller*/ 391 temp = REG_READ(map->cntr); 392 REG_WRITE(map->cntr, 393 temp & ~DISPLAY_PLANE_ENABLE); 394 REG_WRITE(map->base, REG_READ(map->base)); 395 /*mdfld_dsi_dpi_shut_down(dev, pipe);*/ 396 REG_WRITE(0xb048, 1); 397 msleep(100); 398 temp = REG_READ(map->conf); 399 temp &= ~PIPEACONF_ENABLE; 400 REG_WRITE(map->conf, temp); 401 msleep(100); /*wait for pipe disable*/ 402 REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 0); 403 msleep(100); 404 REG_WRITE(0xb004, REG_READ(0xb004)); 405 /* try to bring the controller back up again*/ 406 REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 1); 407 temp = REG_READ(map->cntr); 408 REG_WRITE(map->cntr, 409 temp | DISPLAY_PLANE_ENABLE); 410 REG_WRITE(map->base, REG_READ(map->base)); 411 /*mdfld_dsi_dpi_turn_on(dev, pipe);*/ 412 REG_WRITE(0xb048, 2); 413 msleep(100); 414 temp = REG_READ(map->conf); 415 temp |= PIPEACONF_ENABLE; 416 REG_WRITE(map->conf, temp); 417 } 418 } 419 420 gma_crtc_load_lut(crtc); 421 422 /* Give the overlay scaler a chance to enable 423 if it's on this pipe */ 424 /* psb_intel_crtc_dpms_video(crtc, true); TODO */ 425 426 break; 427 case DRM_MODE_DPMS_OFF: 428 /* Give the overlay scaler a chance to disable 429 * if it's on this pipe */ 430 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ 431 if (pipe != 1) 432 mdfld_dsi_gen_fifo_ready(dev, 433 MIPI_GEN_FIFO_STAT_REG(pipe), 434 HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); 435 436 /* Disable the VGA plane that we never use */ 437 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 438 439 /* Disable display plane */ 440 temp = REG_READ(map->cntr); 441 if ((temp & DISPLAY_PLANE_ENABLE) != 0) { 442 REG_WRITE(map->cntr, 443 temp & ~DISPLAY_PLANE_ENABLE); 444 /* Flush the plane changes */ 445 REG_WRITE(map->base, REG_READ(map->base)); 446 REG_READ(map->base); 447 } 448 449 /* Next, disable display pipes */ 450 temp = REG_READ(map->conf); 451 if ((temp & PIPEACONF_ENABLE) != 0) { 452 temp &= ~PIPEACONF_ENABLE; 453 temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; 454 REG_WRITE(map->conf, temp); 455 REG_READ(map->conf); 456 457 /* Wait for for the pipe disable to take effect. */ 458 mdfldWaitForPipeDisable(dev, pipe); 459 } 460 461 temp = REG_READ(map->dpll); 462 if (temp & DPLL_VCO_ENABLE) { 463 if ((pipe != 1 && !((REG_READ(PIPEACONF) 464 | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE)) 465 || pipe == 1) { 466 temp &= ~(DPLL_VCO_ENABLE); 467 REG_WRITE(map->dpll, temp); 468 REG_READ(map->dpll); 469 /* Wait for the clocks to turn off. */ 470 /* FIXME_MDFLD PO may need more delay */ 471 udelay(500); 472 } 473 } 474 break; 475 } 476 gma_power_end(dev); 477} 478 479 480#define MDFLD_LIMT_DPLL_19 0 481#define MDFLD_LIMT_DPLL_25 1 482#define MDFLD_LIMT_DPLL_83 2 483#define MDFLD_LIMT_DPLL_100 3 484#define MDFLD_LIMT_DSIPLL_19 4 485#define MDFLD_LIMT_DSIPLL_25 5 486#define MDFLD_LIMT_DSIPLL_83 6 487#define MDFLD_LIMT_DSIPLL_100 7 488 489#define MDFLD_DOT_MIN 19750 490#define MDFLD_DOT_MAX 120000 491#define MDFLD_DPLL_M_MIN_19 113 492#define MDFLD_DPLL_M_MAX_19 155 493#define MDFLD_DPLL_P1_MIN_19 2 494#define MDFLD_DPLL_P1_MAX_19 10 495#define MDFLD_DPLL_M_MIN_25 101 496#define MDFLD_DPLL_M_MAX_25 130 497#define MDFLD_DPLL_P1_MIN_25 2 498#define MDFLD_DPLL_P1_MAX_25 10 499#define MDFLD_DPLL_M_MIN_83 64 500#define MDFLD_DPLL_M_MAX_83 64 501#define MDFLD_DPLL_P1_MIN_83 2 502#define MDFLD_DPLL_P1_MAX_83 2 503#define MDFLD_DPLL_M_MIN_100 64 504#define MDFLD_DPLL_M_MAX_100 64 505#define MDFLD_DPLL_P1_MIN_100 2 506#define MDFLD_DPLL_P1_MAX_100 2 507#define MDFLD_DSIPLL_M_MIN_19 131 508#define MDFLD_DSIPLL_M_MAX_19 175 509#define MDFLD_DSIPLL_P1_MIN_19 3 510#define MDFLD_DSIPLL_P1_MAX_19 8 511#define MDFLD_DSIPLL_M_MIN_25 97 512#define MDFLD_DSIPLL_M_MAX_25 140 513#define MDFLD_DSIPLL_P1_MIN_25 3 514#define MDFLD_DSIPLL_P1_MAX_25 9 515#define MDFLD_DSIPLL_M_MIN_83 33 516#define MDFLD_DSIPLL_M_MAX_83 92 517#define MDFLD_DSIPLL_P1_MIN_83 2 518#define MDFLD_DSIPLL_P1_MAX_83 3 519#define MDFLD_DSIPLL_M_MIN_100 97 520#define MDFLD_DSIPLL_M_MAX_100 140 521#define MDFLD_DSIPLL_P1_MIN_100 3 522#define MDFLD_DSIPLL_P1_MAX_100 9 523 524static const struct mrst_limit_t mdfld_limits[] = { 525 { /* MDFLD_LIMT_DPLL_19 */ 526 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 527 .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19}, 528 .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19}, 529 }, 530 { /* MDFLD_LIMT_DPLL_25 */ 531 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 532 .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25}, 533 .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25}, 534 }, 535 { /* MDFLD_LIMT_DPLL_83 */ 536 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 537 .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83}, 538 .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83}, 539 }, 540 { /* MDFLD_LIMT_DPLL_100 */ 541 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 542 .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100}, 543 .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100}, 544 }, 545 { /* MDFLD_LIMT_DSIPLL_19 */ 546 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 547 .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19}, 548 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19}, 549 }, 550 { /* MDFLD_LIMT_DSIPLL_25 */ 551 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 552 .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25}, 553 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25}, 554 }, 555 { /* MDFLD_LIMT_DSIPLL_83 */ 556 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 557 .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83}, 558 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83}, 559 }, 560 { /* MDFLD_LIMT_DSIPLL_100 */ 561 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, 562 .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100}, 563 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100}, 564 }, 565}; 566 567#define MDFLD_M_MIN 21 568#define MDFLD_M_MAX 180 569static const u32 mdfld_m_converts[] = { 570/* M configuration table from 9-bit LFSR table */ 571 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */ 572 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */ 573 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */ 574 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */ 575 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */ 576 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */ 577 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */ 578 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */ 579 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */ 580 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */ 581 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */ 582 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */ 583 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */ 584 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */ 585 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */ 586 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */ 587}; 588 589static const struct mrst_limit_t *mdfld_limit(struct drm_crtc *crtc) 590{ 591 const struct mrst_limit_t *limit = NULL; 592 struct drm_device *dev = crtc->dev; 593 struct drm_psb_private *dev_priv = dev->dev_private; 594 595 if (gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI) 596 || gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) { 597 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) 598 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19]; 599 else if (ksel == KSEL_BYPASS_25) 600 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25]; 601 else if ((ksel == KSEL_BYPASS_83_100) && 602 (dev_priv->core_freq == 166)) 603 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83]; 604 else if ((ksel == KSEL_BYPASS_83_100) && 605 (dev_priv->core_freq == 100 || 606 dev_priv->core_freq == 200)) 607 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100]; 608 } else if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { 609 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) 610 limit = &mdfld_limits[MDFLD_LIMT_DPLL_19]; 611 else if (ksel == KSEL_BYPASS_25) 612 limit = &mdfld_limits[MDFLD_LIMT_DPLL_25]; 613 else if ((ksel == KSEL_BYPASS_83_100) && 614 (dev_priv->core_freq == 166)) 615 limit = &mdfld_limits[MDFLD_LIMT_DPLL_83]; 616 else if ((ksel == KSEL_BYPASS_83_100) && 617 (dev_priv->core_freq == 100 || 618 dev_priv->core_freq == 200)) 619 limit = &mdfld_limits[MDFLD_LIMT_DPLL_100]; 620 } else { 621 limit = NULL; 622 dev_dbg(dev->dev, "mdfld_limit Wrong display type.\n"); 623 } 624 625 return limit; 626} 627 628/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ 629static void mdfld_clock(int refclk, struct mrst_clock_t *clock) 630{ 631 clock->dot = (refclk * clock->m) / clock->p1; 632} 633 634/** 635 * Returns a set of divisors for the desired target clock with the given refclk, 636 * or FALSE. Divisor values are the actual divisors for 637 */ 638static bool 639mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk, 640 struct mrst_clock_t *best_clock) 641{ 642 struct mrst_clock_t clock; 643 const struct mrst_limit_t *limit = mdfld_limit(crtc); 644 int err = target; 645 646 memset(best_clock, 0, sizeof(*best_clock)); 647 648 for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { 649 for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; 650 clock.p1++) { 651 int this_err; 652 653 mdfld_clock(refclk, &clock); 654 655 this_err = abs(clock.dot - target); 656 if (this_err < err) { 657 *best_clock = clock; 658 err = this_err; 659 } 660 } 661 } 662 return err != target; 663} 664 665static int mdfld_crtc_mode_set(struct drm_crtc *crtc, 666 struct drm_display_mode *mode, 667 struct drm_display_mode *adjusted_mode, 668 int x, int y, 669 struct drm_framebuffer *old_fb) 670{ 671 struct drm_device *dev = crtc->dev; 672 struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 673 struct drm_psb_private *dev_priv = dev->dev_private; 674 int pipe = gma_crtc->pipe; 675 const struct psb_offset *map = &dev_priv->regmap[pipe]; 676 int refclk = 0; 677 int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, 678 clk_tmp = 0; 679 struct mrst_clock_t clock; 680 bool ok; 681 u32 dpll = 0, fp = 0; 682 bool is_mipi = false, is_mipi2 = false, is_hdmi = false; 683 struct drm_mode_config *mode_config = &dev->mode_config; 684 struct gma_encoder *gma_encoder = NULL; 685 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; 686 struct drm_encoder *encoder; 687 struct drm_connector *connector; 688 int timeout = 0; 689 int ret; 690 691 dev_dbg(dev->dev, "pipe = 0x%x\n", pipe); 692 693#if 0 694 if (pipe == 1) { 695 if (!gma_power_begin(dev, true)) 696 return 0; 697 android_hdmi_crtc_mode_set(crtc, mode, adjusted_mode, 698 x, y, old_fb); 699 goto mrst_crtc_mode_set_exit; 700 } 701#endif 702 703 ret = check_fb(crtc->primary->fb); 704 if (ret) 705 return ret; 706 707 dev_dbg(dev->dev, "adjusted_hdisplay = %d\n", 708 adjusted_mode->hdisplay); 709 dev_dbg(dev->dev, "adjusted_vdisplay = %d\n", 710 adjusted_mode->vdisplay); 711 dev_dbg(dev->dev, "adjusted_hsync_start = %d\n", 712 adjusted_mode->hsync_start); 713 dev_dbg(dev->dev, "adjusted_hsync_end = %d\n", 714 adjusted_mode->hsync_end); 715 dev_dbg(dev->dev, "adjusted_htotal = %d\n", 716 adjusted_mode->htotal); 717 dev_dbg(dev->dev, "adjusted_vsync_start = %d\n", 718 adjusted_mode->vsync_start); 719 dev_dbg(dev->dev, "adjusted_vsync_end = %d\n", 720 adjusted_mode->vsync_end); 721 dev_dbg(dev->dev, "adjusted_vtotal = %d\n", 722 adjusted_mode->vtotal); 723 dev_dbg(dev->dev, "adjusted_clock = %d\n", 724 adjusted_mode->clock); 725 dev_dbg(dev->dev, "hdisplay = %d\n", 726 mode->hdisplay); 727 dev_dbg(dev->dev, "vdisplay = %d\n", 728 mode->vdisplay); 729 730 if (!gma_power_begin(dev, true)) 731 return 0; 732 733 memcpy(&gma_crtc->saved_mode, mode, 734 sizeof(struct drm_display_mode)); 735 memcpy(&gma_crtc->saved_adjusted_mode, adjusted_mode, 736 sizeof(struct drm_display_mode)); 737 738 list_for_each_entry(connector, &mode_config->connector_list, head) { 739 if (!connector) 740 continue; 741 742 encoder = connector->encoder; 743 744 if (!encoder) 745 continue; 746 747 if (encoder->crtc != crtc) 748 continue; 749 750 gma_encoder = gma_attached_encoder(connector); 751 752 switch (gma_encoder->type) { 753 case INTEL_OUTPUT_MIPI: 754 is_mipi = true; 755 break; 756 case INTEL_OUTPUT_MIPI2: 757 is_mipi2 = true; 758 break; 759 case INTEL_OUTPUT_HDMI: 760 is_hdmi = true; 761 break; 762 } 763 } 764 765 /* Disable the VGA plane that we never use */ 766 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 767 768 /* Disable the panel fitter if it was on our pipe */ 769 if (psb_intel_panel_fitter_pipe(dev) == pipe) 770 REG_WRITE(PFIT_CONTROL, 0); 771 772 /* pipesrc and dspsize control the size that is scaled from, 773 * which should always be the user's requested size. 774 */ 775 if (pipe == 1) { 776 /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 777 * (PYR) or 480x854 (TMD), set the sprite width/height and 778 * souce image size registers with the adjusted mode for 779 * pipe B. 780 */ 781 782 /* 783 * The defined sprite rectangle must always be completely 784 * contained within the displayable area of the screen image 785 * (frame buffer). 786 */ 787 REG_WRITE(map->size, ((min(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16) 788 | (min(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1)); 789 /* Set the CRTC with encoder mode. */ 790 REG_WRITE(map->src, ((mode->crtc_hdisplay - 1) << 16) 791 | (mode->crtc_vdisplay - 1)); 792 } else { 793 REG_WRITE(map->size, 794 ((mode->crtc_vdisplay - 1) << 16) | 795 (mode->crtc_hdisplay - 1)); 796 REG_WRITE(map->src, 797 ((mode->crtc_hdisplay - 1) << 16) | 798 (mode->crtc_vdisplay - 1)); 799 } 800 801 REG_WRITE(map->pos, 0); 802 803 if (gma_encoder) 804 drm_object_property_get_value(&connector->base, 805 dev->mode_config.scaling_mode_property, &scalingType); 806 807 if (scalingType == DRM_MODE_SCALE_NO_SCALE) { 808 /* Medfield doesn't have register support for centering so we 809 * need to mess with the h/vblank and h/vsync start and ends 810 * to get centering 811 */ 812 int offsetX = 0, offsetY = 0; 813 814 offsetX = (adjusted_mode->crtc_hdisplay - 815 mode->crtc_hdisplay) / 2; 816 offsetY = (adjusted_mode->crtc_vdisplay - 817 mode->crtc_vdisplay) / 2; 818 819 REG_WRITE(map->htotal, (mode->crtc_hdisplay - 1) | 820 ((adjusted_mode->crtc_htotal - 1) << 16)); 821 REG_WRITE(map->vtotal, (mode->crtc_vdisplay - 1) | 822 ((adjusted_mode->crtc_vtotal - 1) << 16)); 823 REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 824 offsetX - 1) | 825 ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); 826 REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 827 offsetX - 1) | 828 ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); 829 REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 830 offsetY - 1) | 831 ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); 832 REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 833 offsetY - 1) | 834 ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); 835 } else { 836 REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) | 837 ((adjusted_mode->crtc_htotal - 1) << 16)); 838 REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) | 839 ((adjusted_mode->crtc_vtotal - 1) << 16)); 840 REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) | 841 ((adjusted_mode->crtc_hblank_end - 1) << 16)); 842 REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) | 843 ((adjusted_mode->crtc_hsync_end - 1) << 16)); 844 REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) | 845 ((adjusted_mode->crtc_vblank_end - 1) << 16)); 846 REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) | 847 ((adjusted_mode->crtc_vsync_end - 1) << 16)); 848 } 849 850 /* Flush the plane changes */ 851 { 852 struct drm_crtc_helper_funcs *crtc_funcs = 853 crtc->helper_private; 854 crtc_funcs->mode_set_base(crtc, x, y, old_fb); 855 } 856 857 /* setup pipeconf */ 858 dev_priv->pipeconf[pipe] = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */ 859 860 /* Set up the display plane register */ 861 dev_priv->dspcntr[pipe] = REG_READ(map->cntr); 862 dev_priv->dspcntr[pipe] |= pipe << DISPPLANE_SEL_PIPE_POS; 863 dev_priv->dspcntr[pipe] |= DISPLAY_PLANE_ENABLE; 864 865 if (is_mipi2) 866 goto mrst_crtc_mode_set_exit; 867 clk = adjusted_mode->clock; 868 869 if (is_hdmi) { 870 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) { 871 refclk = 19200; 872 873 if (is_mipi || is_mipi2) 874 clk_n = 1, clk_p2 = 8; 875 else if (is_hdmi) 876 clk_n = 1, clk_p2 = 10; 877 } else if (ksel == KSEL_BYPASS_25) { 878 refclk = 25000; 879 880 if (is_mipi || is_mipi2) 881 clk_n = 1, clk_p2 = 8; 882 else if (is_hdmi) 883 clk_n = 1, clk_p2 = 10; 884 } else if ((ksel == KSEL_BYPASS_83_100) && 885 dev_priv->core_freq == 166) { 886 refclk = 83000; 887 888 if (is_mipi || is_mipi2) 889 clk_n = 4, clk_p2 = 8; 890 else if (is_hdmi) 891 clk_n = 4, clk_p2 = 10; 892 } else if ((ksel == KSEL_BYPASS_83_100) && 893 (dev_priv->core_freq == 100 || 894 dev_priv->core_freq == 200)) { 895 refclk = 100000; 896 if (is_mipi || is_mipi2) 897 clk_n = 4, clk_p2 = 8; 898 else if (is_hdmi) 899 clk_n = 4, clk_p2 = 10; 900 } 901 902 if (is_mipi) 903 clk_byte = dev_priv->bpp / 8; 904 else if (is_mipi2) 905 clk_byte = dev_priv->bpp2 / 8; 906 907 clk_tmp = clk * clk_n * clk_p2 * clk_byte; 908 909 dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d.\n", 910 clk, clk_n, clk_p2); 911 dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d.\n", 912 adjusted_mode->clock, clk_tmp); 913 914 ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock); 915 916 if (!ok) { 917 DRM_ERROR 918 ("mdfldFindBestPLL fail in mdfld_crtc_mode_set.\n"); 919 } else { 920 m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)]; 921 922 dev_dbg(dev->dev, "dot clock = %d," 923 "m = %d, p1 = %d, m_conv = %d.\n", 924 clock.dot, clock.m, 925 clock.p1, m_conv); 926 } 927 928 dpll = REG_READ(map->dpll); 929 930 if (dpll & DPLL_VCO_ENABLE) { 931 dpll &= ~DPLL_VCO_ENABLE; 932 REG_WRITE(map->dpll, dpll); 933 REG_READ(map->dpll); 934 935 /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */ 936 /* FIXME_MDFLD PO - change 500 to 1 after PO */ 937 udelay(500); 938 939 /* reset M1, N1 & P1 */ 940 REG_WRITE(map->fp0, 0); 941 dpll &= ~MDFLD_P1_MASK; 942 REG_WRITE(map->dpll, dpll); 943 /* FIXME_MDFLD PO - change 500 to 1 after PO */ 944 udelay(500); 945 } 946 947 /* When ungating power of DPLL, needs to wait 0.5us before 948 * enable the VCO */ 949 if (dpll & MDFLD_PWR_GATE_EN) { 950 dpll &= ~MDFLD_PWR_GATE_EN; 951 REG_WRITE(map->dpll, dpll); 952 /* FIXME_MDFLD PO - change 500 to 1 after PO */ 953 udelay(500); 954 } 955 dpll = 0; 956 957#if 0 /* FIXME revisit later */ 958 if (ksel == KSEL_CRYSTAL_19 || ksel == KSEL_BYPASS_19 || 959 ksel == KSEL_BYPASS_25) 960 dpll &= ~MDFLD_INPUT_REF_SEL; 961 else if (ksel == KSEL_BYPASS_83_100) 962 dpll |= MDFLD_INPUT_REF_SEL; 963#endif /* FIXME revisit later */ 964 965 if (is_hdmi) 966 dpll |= MDFLD_VCO_SEL; 967 968 fp = (clk_n / 2) << 16; 969 fp |= m_conv; 970 971 /* compute bitmask from p1 value */ 972 dpll |= (1 << (clock.p1 - 2)) << 17; 973 974#if 0 /* 1080p30 & 720p */ 975 dpll = 0x00050000; 976 fp = 0x000001be; 977#endif 978#if 0 /* 480p */ 979 dpll = 0x02010000; 980 fp = 0x000000d2; 981#endif 982 } else { 983#if 0 /*DBI_TPO_480x864*/ 984 dpll = 0x00020000; 985 fp = 0x00000156; 986#endif /* DBI_TPO_480x864 */ /* get from spec. */ 987 988 dpll = 0x00800000; 989 fp = 0x000000c1; 990 } 991 992 REG_WRITE(map->fp0, fp); 993 REG_WRITE(map->dpll, dpll); 994 /* FIXME_MDFLD PO - change 500 to 1 after PO */ 995 udelay(500); 996 997 dpll |= DPLL_VCO_ENABLE; 998 REG_WRITE(map->dpll, dpll); 999 REG_READ(map->dpll); 1000 1001 /* wait for DSI PLL to lock */ 1002 while (timeout < 20000 && 1003 !(REG_READ(map->conf) & PIPECONF_DSIPLL_LOCK)) { 1004 udelay(150); 1005 timeout++; 1006 } 1007 1008 if (is_mipi) 1009 goto mrst_crtc_mode_set_exit; 1010 1011 dev_dbg(dev->dev, "is_mipi = 0x%x\n", is_mipi); 1012 1013 REG_WRITE(map->conf, dev_priv->pipeconf[pipe]); 1014 REG_READ(map->conf); 1015 1016 /* Wait for for the pipe enable to take effect. */ 1017 REG_WRITE(map->cntr, dev_priv->dspcntr[pipe]); 1018 gma_wait_for_vblank(dev); 1019 1020mrst_crtc_mode_set_exit: 1021 1022 gma_power_end(dev); 1023 1024 return 0; 1025} 1026 1027const struct drm_crtc_helper_funcs mdfld_helper_funcs = { 1028 .dpms = mdfld_crtc_dpms, 1029 .mode_fixup = gma_crtc_mode_fixup, 1030 .mode_set = mdfld_crtc_mode_set, 1031 .mode_set_base = mdfld__intel_pipe_set_base, 1032 .prepare = gma_crtc_prepare, 1033 .commit = gma_crtc_commit, 1034}; 1035 1036