1/************************************************************************** 2 * Copyright (c) 2011, Intel Corporation. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 **************************************************************************/ 19 20#include "psb_drv.h" 21#include "mid_bios.h" 22#include "mdfld_output.h" 23#include "mdfld_dsi_output.h" 24#include "tc35876x-dsi-lvds.h" 25 26#include <asm/intel_scu_ipc.h> 27 28#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 29 30#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF 31#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ 32#define BLC_PWM_FREQ_CALC_CONSTANT 32 33#define MHz 1000000 34#define BRIGHTNESS_MIN_LEVEL 1 35#define BRIGHTNESS_MAX_LEVEL 100 36#define BRIGHTNESS_MASK 0xFF 37#define BLC_POLARITY_NORMAL 0 38#define BLC_POLARITY_INVERSE 1 39#define BLC_ADJUSTMENT_MAX 100 40 41#define MDFLD_BLC_PWM_PRECISION_FACTOR 10 42#define MDFLD_BLC_MAX_PWM_REG_FREQ 0xFFFE 43#define MDFLD_BLC_MIN_PWM_REG_FREQ 0x2 44 45#define MDFLD_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) 46#define MDFLD_BACKLIGHT_PWM_CTL_SHIFT (16) 47 48static struct backlight_device *mdfld_backlight_device; 49 50int mdfld_set_brightness(struct backlight_device *bd) 51{ 52 struct drm_device *dev = 53 (struct drm_device *)bl_get_data(mdfld_backlight_device); 54 struct drm_psb_private *dev_priv = dev->dev_private; 55 int level = bd->props.brightness; 56 57 DRM_DEBUG_DRIVER("backlight level set to %d\n", level); 58 59 /* Perform value bounds checking */ 60 if (level < BRIGHTNESS_MIN_LEVEL) 61 level = BRIGHTNESS_MIN_LEVEL; 62 63 if (gma_power_begin(dev, false)) { 64 u32 adjusted_level = 0; 65 66 /* 67 * Adjust the backlight level with the percent in 68 * dev_priv->blc_adj2 69 */ 70 adjusted_level = level * dev_priv->blc_adj2; 71 adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX; 72 dev_priv->brightness_adjusted = adjusted_level; 73 74 if (mdfld_get_panel_type(dev, 0) == TC35876X) { 75 if (dev_priv->dpi_panel_on[0] || 76 dev_priv->dpi_panel_on[2]) 77 tc35876x_brightness_control(dev, 78 dev_priv->brightness_adjusted); 79 } else { 80 if (dev_priv->dpi_panel_on[0]) 81 mdfld_dsi_brightness_control(dev, 0, 82 dev_priv->brightness_adjusted); 83 } 84 85 if (dev_priv->dpi_panel_on[2]) 86 mdfld_dsi_brightness_control(dev, 2, 87 dev_priv->brightness_adjusted); 88 gma_power_end(dev); 89 } 90 91 /* cache the brightness for later use */ 92 dev_priv->brightness = level; 93 return 0; 94} 95 96static int mdfld_get_brightness(struct backlight_device *bd) 97{ 98 struct drm_device *dev = 99 (struct drm_device *)bl_get_data(mdfld_backlight_device); 100 struct drm_psb_private *dev_priv = dev->dev_private; 101 102 DRM_DEBUG_DRIVER("brightness = 0x%x \n", dev_priv->brightness); 103 104 /* return locally cached var instead of HW read (due to DPST etc.) */ 105 return dev_priv->brightness; 106} 107 108static const struct backlight_ops mdfld_ops = { 109 .get_brightness = mdfld_get_brightness, 110 .update_status = mdfld_set_brightness, 111}; 112 113static int device_backlight_init(struct drm_device *dev) 114{ 115 struct drm_psb_private *dev_priv = (struct drm_psb_private *) 116 dev->dev_private; 117 118 dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; 119 dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; 120 121 return 0; 122} 123 124static int mdfld_backlight_init(struct drm_device *dev) 125{ 126 struct backlight_properties props; 127 int ret = 0; 128 129 memset(&props, 0, sizeof(struct backlight_properties)); 130 props.max_brightness = BRIGHTNESS_MAX_LEVEL; 131 props.type = BACKLIGHT_PLATFORM; 132 mdfld_backlight_device = backlight_device_register("mdfld-bl", 133 NULL, (void *)dev, &mdfld_ops, &props); 134 135 if (IS_ERR(mdfld_backlight_device)) 136 return PTR_ERR(mdfld_backlight_device); 137 138 ret = device_backlight_init(dev); 139 if (ret) 140 return ret; 141 142 mdfld_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL; 143 mdfld_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL; 144 backlight_update_status(mdfld_backlight_device); 145 return 0; 146} 147#endif 148 149struct backlight_device *mdfld_get_backlight_device(void) 150{ 151#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 152 return mdfld_backlight_device; 153#else 154 return NULL; 155#endif 156} 157 158/* 159 * mdfld_save_display_registers 160 * 161 * Description: We are going to suspend so save current display 162 * register state. 163 * 164 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio 165 */ 166static int mdfld_save_display_registers(struct drm_device *dev, int pipe) 167{ 168 struct drm_psb_private *dev_priv = dev->dev_private; 169 struct medfield_state *regs = &dev_priv->regs.mdfld; 170 int i; 171 172 /* register */ 173 u32 dpll_reg = MRST_DPLL_A; 174 u32 fp_reg = MRST_FPA0; 175 u32 pipeconf_reg = PIPEACONF; 176 u32 htot_reg = HTOTAL_A; 177 u32 hblank_reg = HBLANK_A; 178 u32 hsync_reg = HSYNC_A; 179 u32 vtot_reg = VTOTAL_A; 180 u32 vblank_reg = VBLANK_A; 181 u32 vsync_reg = VSYNC_A; 182 u32 pipesrc_reg = PIPEASRC; 183 u32 dspstride_reg = DSPASTRIDE; 184 u32 dsplinoff_reg = DSPALINOFF; 185 u32 dsptileoff_reg = DSPATILEOFF; 186 u32 dspsize_reg = DSPASIZE; 187 u32 dsppos_reg = DSPAPOS; 188 u32 dspsurf_reg = DSPASURF; 189 u32 mipi_reg = MIPI; 190 u32 dspcntr_reg = DSPACNTR; 191 u32 dspstatus_reg = PIPEASTAT; 192 u32 palette_reg = PALETTE_A; 193 194 /* pointer to values */ 195 u32 *dpll_val = ®s->saveDPLL_A; 196 u32 *fp_val = ®s->saveFPA0; 197 u32 *pipeconf_val = ®s->savePIPEACONF; 198 u32 *htot_val = ®s->saveHTOTAL_A; 199 u32 *hblank_val = ®s->saveHBLANK_A; 200 u32 *hsync_val = ®s->saveHSYNC_A; 201 u32 *vtot_val = ®s->saveVTOTAL_A; 202 u32 *vblank_val = ®s->saveVBLANK_A; 203 u32 *vsync_val = ®s->saveVSYNC_A; 204 u32 *pipesrc_val = ®s->savePIPEASRC; 205 u32 *dspstride_val = ®s->saveDSPASTRIDE; 206 u32 *dsplinoff_val = ®s->saveDSPALINOFF; 207 u32 *dsptileoff_val = ®s->saveDSPATILEOFF; 208 u32 *dspsize_val = ®s->saveDSPASIZE; 209 u32 *dsppos_val = ®s->saveDSPAPOS; 210 u32 *dspsurf_val = ®s->saveDSPASURF; 211 u32 *mipi_val = ®s->saveMIPI; 212 u32 *dspcntr_val = ®s->saveDSPACNTR; 213 u32 *dspstatus_val = ®s->saveDSPASTATUS; 214 u32 *palette_val = regs->save_palette_a; 215 216 switch (pipe) { 217 case 0: 218 break; 219 case 1: 220 /* regester */ 221 dpll_reg = MDFLD_DPLL_B; 222 fp_reg = MDFLD_DPLL_DIV0; 223 pipeconf_reg = PIPEBCONF; 224 htot_reg = HTOTAL_B; 225 hblank_reg = HBLANK_B; 226 hsync_reg = HSYNC_B; 227 vtot_reg = VTOTAL_B; 228 vblank_reg = VBLANK_B; 229 vsync_reg = VSYNC_B; 230 pipesrc_reg = PIPEBSRC; 231 dspstride_reg = DSPBSTRIDE; 232 dsplinoff_reg = DSPBLINOFF; 233 dsptileoff_reg = DSPBTILEOFF; 234 dspsize_reg = DSPBSIZE; 235 dsppos_reg = DSPBPOS; 236 dspsurf_reg = DSPBSURF; 237 dspcntr_reg = DSPBCNTR; 238 dspstatus_reg = PIPEBSTAT; 239 palette_reg = PALETTE_B; 240 241 /* values */ 242 dpll_val = ®s->saveDPLL_B; 243 fp_val = ®s->saveFPB0; 244 pipeconf_val = ®s->savePIPEBCONF; 245 htot_val = ®s->saveHTOTAL_B; 246 hblank_val = ®s->saveHBLANK_B; 247 hsync_val = ®s->saveHSYNC_B; 248 vtot_val = ®s->saveVTOTAL_B; 249 vblank_val = ®s->saveVBLANK_B; 250 vsync_val = ®s->saveVSYNC_B; 251 pipesrc_val = ®s->savePIPEBSRC; 252 dspstride_val = ®s->saveDSPBSTRIDE; 253 dsplinoff_val = ®s->saveDSPBLINOFF; 254 dsptileoff_val = ®s->saveDSPBTILEOFF; 255 dspsize_val = ®s->saveDSPBSIZE; 256 dsppos_val = ®s->saveDSPBPOS; 257 dspsurf_val = ®s->saveDSPBSURF; 258 dspcntr_val = ®s->saveDSPBCNTR; 259 dspstatus_val = ®s->saveDSPBSTATUS; 260 palette_val = regs->save_palette_b; 261 break; 262 case 2: 263 /* register */ 264 pipeconf_reg = PIPECCONF; 265 htot_reg = HTOTAL_C; 266 hblank_reg = HBLANK_C; 267 hsync_reg = HSYNC_C; 268 vtot_reg = VTOTAL_C; 269 vblank_reg = VBLANK_C; 270 vsync_reg = VSYNC_C; 271 pipesrc_reg = PIPECSRC; 272 dspstride_reg = DSPCSTRIDE; 273 dsplinoff_reg = DSPCLINOFF; 274 dsptileoff_reg = DSPCTILEOFF; 275 dspsize_reg = DSPCSIZE; 276 dsppos_reg = DSPCPOS; 277 dspsurf_reg = DSPCSURF; 278 mipi_reg = MIPI_C; 279 dspcntr_reg = DSPCCNTR; 280 dspstatus_reg = PIPECSTAT; 281 palette_reg = PALETTE_C; 282 283 /* pointer to values */ 284 pipeconf_val = ®s->savePIPECCONF; 285 htot_val = ®s->saveHTOTAL_C; 286 hblank_val = ®s->saveHBLANK_C; 287 hsync_val = ®s->saveHSYNC_C; 288 vtot_val = ®s->saveVTOTAL_C; 289 vblank_val = ®s->saveVBLANK_C; 290 vsync_val = ®s->saveVSYNC_C; 291 pipesrc_val = ®s->savePIPECSRC; 292 dspstride_val = ®s->saveDSPCSTRIDE; 293 dsplinoff_val = ®s->saveDSPCLINOFF; 294 dsptileoff_val = ®s->saveDSPCTILEOFF; 295 dspsize_val = ®s->saveDSPCSIZE; 296 dsppos_val = ®s->saveDSPCPOS; 297 dspsurf_val = ®s->saveDSPCSURF; 298 mipi_val = ®s->saveMIPI_C; 299 dspcntr_val = ®s->saveDSPCCNTR; 300 dspstatus_val = ®s->saveDSPCSTATUS; 301 palette_val = regs->save_palette_c; 302 break; 303 default: 304 DRM_ERROR("%s, invalid pipe number.\n", __func__); 305 return -EINVAL; 306 } 307 308 /* Pipe & plane A info */ 309 *dpll_val = PSB_RVDC32(dpll_reg); 310 *fp_val = PSB_RVDC32(fp_reg); 311 *pipeconf_val = PSB_RVDC32(pipeconf_reg); 312 *htot_val = PSB_RVDC32(htot_reg); 313 *hblank_val = PSB_RVDC32(hblank_reg); 314 *hsync_val = PSB_RVDC32(hsync_reg); 315 *vtot_val = PSB_RVDC32(vtot_reg); 316 *vblank_val = PSB_RVDC32(vblank_reg); 317 *vsync_val = PSB_RVDC32(vsync_reg); 318 *pipesrc_val = PSB_RVDC32(pipesrc_reg); 319 *dspstride_val = PSB_RVDC32(dspstride_reg); 320 *dsplinoff_val = PSB_RVDC32(dsplinoff_reg); 321 *dsptileoff_val = PSB_RVDC32(dsptileoff_reg); 322 *dspsize_val = PSB_RVDC32(dspsize_reg); 323 *dsppos_val = PSB_RVDC32(dsppos_reg); 324 *dspsurf_val = PSB_RVDC32(dspsurf_reg); 325 *dspcntr_val = PSB_RVDC32(dspcntr_reg); 326 *dspstatus_val = PSB_RVDC32(dspstatus_reg); 327 328 /*save palette (gamma) */ 329 for (i = 0; i < 256; i++) 330 palette_val[i] = PSB_RVDC32(palette_reg + (i << 2)); 331 332 if (pipe == 1) { 333 regs->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); 334 regs->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); 335 336 regs->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL); 337 regs->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL); 338 return 0; 339 } 340 341 *mipi_val = PSB_RVDC32(mipi_reg); 342 return 0; 343} 344 345/* 346 * mdfld_restore_display_registers 347 * 348 * Description: We are going to resume so restore display register state. 349 * 350 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio 351 */ 352static int mdfld_restore_display_registers(struct drm_device *dev, int pipe) 353{ 354 /* To get panel out of ULPS mode. */ 355 u32 temp = 0; 356 u32 device_ready_reg = DEVICE_READY_REG; 357 struct drm_psb_private *dev_priv = dev->dev_private; 358 struct mdfld_dsi_config *dsi_config = NULL; 359 struct medfield_state *regs = &dev_priv->regs.mdfld; 360 u32 i = 0; 361 u32 dpll = 0; 362 u32 timeout = 0; 363 364 /* regester */ 365 u32 dpll_reg = MRST_DPLL_A; 366 u32 fp_reg = MRST_FPA0; 367 u32 pipeconf_reg = PIPEACONF; 368 u32 htot_reg = HTOTAL_A; 369 u32 hblank_reg = HBLANK_A; 370 u32 hsync_reg = HSYNC_A; 371 u32 vtot_reg = VTOTAL_A; 372 u32 vblank_reg = VBLANK_A; 373 u32 vsync_reg = VSYNC_A; 374 u32 pipesrc_reg = PIPEASRC; 375 u32 dspstride_reg = DSPASTRIDE; 376 u32 dsplinoff_reg = DSPALINOFF; 377 u32 dsptileoff_reg = DSPATILEOFF; 378 u32 dspsize_reg = DSPASIZE; 379 u32 dsppos_reg = DSPAPOS; 380 u32 dspsurf_reg = DSPASURF; 381 u32 dspstatus_reg = PIPEASTAT; 382 u32 mipi_reg = MIPI; 383 u32 dspcntr_reg = DSPACNTR; 384 u32 palette_reg = PALETTE_A; 385 386 /* values */ 387 u32 dpll_val = regs->saveDPLL_A & ~DPLL_VCO_ENABLE; 388 u32 fp_val = regs->saveFPA0; 389 u32 pipeconf_val = regs->savePIPEACONF; 390 u32 htot_val = regs->saveHTOTAL_A; 391 u32 hblank_val = regs->saveHBLANK_A; 392 u32 hsync_val = regs->saveHSYNC_A; 393 u32 vtot_val = regs->saveVTOTAL_A; 394 u32 vblank_val = regs->saveVBLANK_A; 395 u32 vsync_val = regs->saveVSYNC_A; 396 u32 pipesrc_val = regs->savePIPEASRC; 397 u32 dspstride_val = regs->saveDSPASTRIDE; 398 u32 dsplinoff_val = regs->saveDSPALINOFF; 399 u32 dsptileoff_val = regs->saveDSPATILEOFF; 400 u32 dspsize_val = regs->saveDSPASIZE; 401 u32 dsppos_val = regs->saveDSPAPOS; 402 u32 dspsurf_val = regs->saveDSPASURF; 403 u32 dspstatus_val = regs->saveDSPASTATUS; 404 u32 mipi_val = regs->saveMIPI; 405 u32 dspcntr_val = regs->saveDSPACNTR; 406 u32 *palette_val = regs->save_palette_a; 407 408 switch (pipe) { 409 case 0: 410 dsi_config = dev_priv->dsi_configs[0]; 411 break; 412 case 1: 413 /* regester */ 414 dpll_reg = MDFLD_DPLL_B; 415 fp_reg = MDFLD_DPLL_DIV0; 416 pipeconf_reg = PIPEBCONF; 417 htot_reg = HTOTAL_B; 418 hblank_reg = HBLANK_B; 419 hsync_reg = HSYNC_B; 420 vtot_reg = VTOTAL_B; 421 vblank_reg = VBLANK_B; 422 vsync_reg = VSYNC_B; 423 pipesrc_reg = PIPEBSRC; 424 dspstride_reg = DSPBSTRIDE; 425 dsplinoff_reg = DSPBLINOFF; 426 dsptileoff_reg = DSPBTILEOFF; 427 dspsize_reg = DSPBSIZE; 428 dsppos_reg = DSPBPOS; 429 dspsurf_reg = DSPBSURF; 430 dspcntr_reg = DSPBCNTR; 431 dspstatus_reg = PIPEBSTAT; 432 palette_reg = PALETTE_B; 433 434 /* values */ 435 dpll_val = regs->saveDPLL_B & ~DPLL_VCO_ENABLE; 436 fp_val = regs->saveFPB0; 437 pipeconf_val = regs->savePIPEBCONF; 438 htot_val = regs->saveHTOTAL_B; 439 hblank_val = regs->saveHBLANK_B; 440 hsync_val = regs->saveHSYNC_B; 441 vtot_val = regs->saveVTOTAL_B; 442 vblank_val = regs->saveVBLANK_B; 443 vsync_val = regs->saveVSYNC_B; 444 pipesrc_val = regs->savePIPEBSRC; 445 dspstride_val = regs->saveDSPBSTRIDE; 446 dsplinoff_val = regs->saveDSPBLINOFF; 447 dsptileoff_val = regs->saveDSPBTILEOFF; 448 dspsize_val = regs->saveDSPBSIZE; 449 dsppos_val = regs->saveDSPBPOS; 450 dspsurf_val = regs->saveDSPBSURF; 451 dspcntr_val = regs->saveDSPBCNTR; 452 dspstatus_val = regs->saveDSPBSTATUS; 453 palette_val = regs->save_palette_b; 454 break; 455 case 2: 456 /* regester */ 457 pipeconf_reg = PIPECCONF; 458 htot_reg = HTOTAL_C; 459 hblank_reg = HBLANK_C; 460 hsync_reg = HSYNC_C; 461 vtot_reg = VTOTAL_C; 462 vblank_reg = VBLANK_C; 463 vsync_reg = VSYNC_C; 464 pipesrc_reg = PIPECSRC; 465 dspstride_reg = DSPCSTRIDE; 466 dsplinoff_reg = DSPCLINOFF; 467 dsptileoff_reg = DSPCTILEOFF; 468 dspsize_reg = DSPCSIZE; 469 dsppos_reg = DSPCPOS; 470 dspsurf_reg = DSPCSURF; 471 mipi_reg = MIPI_C; 472 dspcntr_reg = DSPCCNTR; 473 dspstatus_reg = PIPECSTAT; 474 palette_reg = PALETTE_C; 475 476 /* values */ 477 pipeconf_val = regs->savePIPECCONF; 478 htot_val = regs->saveHTOTAL_C; 479 hblank_val = regs->saveHBLANK_C; 480 hsync_val = regs->saveHSYNC_C; 481 vtot_val = regs->saveVTOTAL_C; 482 vblank_val = regs->saveVBLANK_C; 483 vsync_val = regs->saveVSYNC_C; 484 pipesrc_val = regs->savePIPECSRC; 485 dspstride_val = regs->saveDSPCSTRIDE; 486 dsplinoff_val = regs->saveDSPCLINOFF; 487 dsptileoff_val = regs->saveDSPCTILEOFF; 488 dspsize_val = regs->saveDSPCSIZE; 489 dsppos_val = regs->saveDSPCPOS; 490 dspsurf_val = regs->saveDSPCSURF; 491 mipi_val = regs->saveMIPI_C; 492 dspcntr_val = regs->saveDSPCCNTR; 493 dspstatus_val = regs->saveDSPCSTATUS; 494 palette_val = regs->save_palette_c; 495 496 dsi_config = dev_priv->dsi_configs[1]; 497 break; 498 default: 499 DRM_ERROR("%s, invalid pipe number.\n", __func__); 500 return -EINVAL; 501 } 502 503 /*make sure VGA plane is off. it initializes to on after reset!*/ 504 PSB_WVDC32(0x80000000, VGACNTRL); 505 506 if (pipe == 1) { 507 PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg); 508 PSB_RVDC32(dpll_reg); 509 510 PSB_WVDC32(fp_val, fp_reg); 511 } else { 512 513 dpll = PSB_RVDC32(dpll_reg); 514 515 if (!(dpll & DPLL_VCO_ENABLE)) { 516 517 /* When ungating power of DPLL, needs to wait 0.5us 518 before enable the VCO */ 519 if (dpll & MDFLD_PWR_GATE_EN) { 520 dpll &= ~MDFLD_PWR_GATE_EN; 521 PSB_WVDC32(dpll, dpll_reg); 522 /* FIXME_MDFLD PO - change 500 to 1 after PO */ 523 udelay(500); 524 } 525 526 PSB_WVDC32(fp_val, fp_reg); 527 PSB_WVDC32(dpll_val, dpll_reg); 528 /* FIXME_MDFLD PO - change 500 to 1 after PO */ 529 udelay(500); 530 531 dpll_val |= DPLL_VCO_ENABLE; 532 PSB_WVDC32(dpll_val, dpll_reg); 533 PSB_RVDC32(dpll_reg); 534 535 /* wait for DSI PLL to lock */ 536 while (timeout < 20000 && 537 !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { 538 udelay(150); 539 timeout++; 540 } 541 542 if (timeout == 20000) { 543 DRM_ERROR("%s, can't lock DSIPLL.\n", 544 __func__); 545 return -EINVAL; 546 } 547 } 548 } 549 /* Restore mode */ 550 PSB_WVDC32(htot_val, htot_reg); 551 PSB_WVDC32(hblank_val, hblank_reg); 552 PSB_WVDC32(hsync_val, hsync_reg); 553 PSB_WVDC32(vtot_val, vtot_reg); 554 PSB_WVDC32(vblank_val, vblank_reg); 555 PSB_WVDC32(vsync_val, vsync_reg); 556 PSB_WVDC32(pipesrc_val, pipesrc_reg); 557 PSB_WVDC32(dspstatus_val, dspstatus_reg); 558 559 /*set up the plane*/ 560 PSB_WVDC32(dspstride_val, dspstride_reg); 561 PSB_WVDC32(dsplinoff_val, dsplinoff_reg); 562 PSB_WVDC32(dsptileoff_val, dsptileoff_reg); 563 PSB_WVDC32(dspsize_val, dspsize_reg); 564 PSB_WVDC32(dsppos_val, dsppos_reg); 565 PSB_WVDC32(dspsurf_val, dspsurf_reg); 566 567 if (pipe == 1) { 568 /* restore palette (gamma) */ 569 /*DRM_UDELAY(50000); */ 570 for (i = 0; i < 256; i++) 571 PSB_WVDC32(palette_val[i], palette_reg + (i << 2)); 572 573 PSB_WVDC32(regs->savePFIT_CONTROL, PFIT_CONTROL); 574 PSB_WVDC32(regs->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); 575 576 /*TODO: resume HDMI port */ 577 578 /*TODO: resume pipe*/ 579 580 /*enable the plane*/ 581 PSB_WVDC32(dspcntr_val & ~DISPLAY_PLANE_ENABLE, dspcntr_reg); 582 583 return 0; 584 } 585 586 /*set up pipe related registers*/ 587 PSB_WVDC32(mipi_val, mipi_reg); 588 589 /*setup MIPI adapter + MIPI IP registers*/ 590 if (dsi_config) 591 mdfld_dsi_controller_init(dsi_config, pipe); 592 593 if (in_atomic() || in_interrupt()) 594 mdelay(20); 595 else 596 msleep(20); 597 598 /*enable the plane*/ 599 PSB_WVDC32(dspcntr_val, dspcntr_reg); 600 601 if (in_atomic() || in_interrupt()) 602 mdelay(20); 603 else 604 msleep(20); 605 606 /* LP Hold Release */ 607 temp = REG_READ(mipi_reg); 608 temp |= LP_OUTPUT_HOLD_RELEASE; 609 REG_WRITE(mipi_reg, temp); 610 mdelay(1); 611 612 613 /* Set DSI host to exit from Utra Low Power State */ 614 temp = REG_READ(device_ready_reg); 615 temp &= ~ULPS_MASK; 616 temp |= 0x3; 617 temp |= EXIT_ULPS_DEV_READY; 618 REG_WRITE(device_ready_reg, temp); 619 mdelay(1); 620 621 temp = REG_READ(device_ready_reg); 622 temp &= ~ULPS_MASK; 623 temp |= EXITING_ULPS; 624 REG_WRITE(device_ready_reg, temp); 625 mdelay(1); 626 627 /*enable the pipe*/ 628 PSB_WVDC32(pipeconf_val, pipeconf_reg); 629 630 /* restore palette (gamma) */ 631 /*DRM_UDELAY(50000); */ 632 for (i = 0; i < 256; i++) 633 PSB_WVDC32(palette_val[i], palette_reg + (i << 2)); 634 635 return 0; 636} 637 638static int mdfld_save_registers(struct drm_device *dev) 639{ 640 /* mdfld_save_cursor_overlay_registers(dev); */ 641 mdfld_save_display_registers(dev, 0); 642 mdfld_save_display_registers(dev, 2); 643 mdfld_disable_crtc(dev, 0); 644 mdfld_disable_crtc(dev, 2); 645 646 return 0; 647} 648 649static int mdfld_restore_registers(struct drm_device *dev) 650{ 651 mdfld_restore_display_registers(dev, 2); 652 mdfld_restore_display_registers(dev, 0); 653 /* mdfld_restore_cursor_overlay_registers(dev); */ 654 655 return 0; 656} 657 658static int mdfld_power_down(struct drm_device *dev) 659{ 660 /* FIXME */ 661 return 0; 662} 663 664static int mdfld_power_up(struct drm_device *dev) 665{ 666 /* FIXME */ 667 return 0; 668} 669 670const struct psb_ops mdfld_chip_ops = { 671 .name = "mdfld", 672 .accel_2d = 0, 673 .pipes = 3, 674 .crtcs = 3, 675 .sgx_offset = MRST_SGX_OFFSET, 676 677 .chip_setup = mid_chip_setup, 678 .crtc_helper = &mdfld_helper_funcs, 679 .crtc_funcs = &psb_intel_crtc_funcs, 680 681 .output_init = mdfld_output_init, 682 683#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 684 .backlight_init = mdfld_backlight_init, 685#endif 686 687 .save_regs = mdfld_save_registers, 688 .restore_regs = mdfld_restore_registers, 689 .power_down = mdfld_power_down, 690 .power_up = mdfld_power_up, 691}; 692