1/* 2 * 3 * Copyright (c) 2012 Gilles Dartiguelongue, Thomas Richter 4 * 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD$"); 31 32#include "dvo.h" 33#include "i915_reg.h" 34#include "i915_drv.h" 35 36#define NS2501_VID 0x1305 37#define NS2501_DID 0x6726 38 39#define NS2501_VID_LO 0x00 40#define NS2501_VID_HI 0x01 41#define NS2501_DID_LO 0x02 42#define NS2501_DID_HI 0x03 43#define NS2501_REV 0x04 44#define NS2501_RSVD 0x05 45#define NS2501_FREQ_LO 0x06 46#define NS2501_FREQ_HI 0x07 47 48#define NS2501_REG8 0x08 49#define NS2501_8_VEN (1<<5) 50#define NS2501_8_HEN (1<<4) 51#define NS2501_8_DSEL (1<<3) 52#define NS2501_8_BPAS (1<<2) 53#define NS2501_8_RSVD (1<<1) 54#define NS2501_8_PD (1<<0) 55 56#define NS2501_REG9 0x09 57#define NS2501_9_VLOW (1<<7) 58#define NS2501_9_MSEL_MASK (0x7<<4) 59#define NS2501_9_TSEL (1<<3) 60#define NS2501_9_RSEN (1<<2) 61#define NS2501_9_RSVD (1<<1) 62#define NS2501_9_MDI (1<<0) 63 64#define NS2501_REGC 0x0c 65 66struct ns2501_priv { 67 //I2CDevRec d; 68 bool quiet; 69 int reg_8_shadow; 70 int reg_8_set; 71 // Shadow registers for i915 72 int dvoc; 73 int pll_a; 74 int srcdim; 75 int fw_blc; 76}; 77 78#define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr)) 79 80/* 81 * For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens 82 * laptops does not react on the i2c bus unless 83 * both the PLL is running and the display is configured in its native 84 * resolution. 85 * This function forces the DVO on, and stores the registers it touches. 86 * Afterwards, registers are restored to regular values. 87 * 88 * This is pretty much a hack, though it works. 89 * Without that, ns2501_readb and ns2501_writeb fail 90 * when switching the resolution. 91 */ 92 93static void enable_dvo(struct intel_dvo_device *dvo) 94{ 95 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); 96 device_t adapter = dvo->i2c_bus; 97 /* 98 * FIXME Linux<->FreeBSD: device_get_softc() returns a struct 99 * intel_iic_softc in reality, where struct intel_gmbus is 100 * the first member. struct intel_iic_softc is defined in 101 * intel_iic.c. 102 */ 103 struct intel_gmbus *bus = 104 (struct intel_gmbus *)device_get_softc(adapter); 105 struct drm_i915_private *dev_priv = bus->dev_priv; 106 107 DRM_DEBUG_KMS("%s: Trying to re-enable the DVO\n", __FUNCTION__); 108 109 ns->dvoc = I915_READ(DVO_C); 110 ns->pll_a = I915_READ(_DPLL_A); 111 ns->srcdim = I915_READ(DVOC_SRCDIM); 112 ns->fw_blc = I915_READ(FW_BLC); 113 114 I915_WRITE(DVOC, 0x10004084); 115 I915_WRITE(_DPLL_A, 0xd0820000); 116 I915_WRITE(DVOC_SRCDIM, 0x400300); // 1024x768 117 I915_WRITE(FW_BLC, 0x1080304); 118 119 I915_WRITE(DVOC, 0x90004084); 120} 121 122/* 123 * Restore the I915 registers modified by the above 124 * trigger function. 125 */ 126static void restore_dvo(struct intel_dvo_device *dvo) 127{ 128 device_t adapter = dvo->i2c_bus; 129 /* 130 * FIXME Linux<->FreeBSD: device_get_softc() returns a struct 131 * intel_iic_softc in reality, where struct intel_gmbus is 132 * the first member. struct intel_iic_softc is defined in 133 * intel_iic.c. 134 */ 135 struct intel_gmbus *bus = 136 (struct intel_gmbus *)device_get_softc(adapter); 137 struct drm_i915_private *dev_priv = bus->dev_priv; 138 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); 139 140 I915_WRITE(DVOC, ns->dvoc); 141 I915_WRITE(_DPLL_A, ns->pll_a); 142 I915_WRITE(DVOC_SRCDIM, ns->srcdim); 143 I915_WRITE(FW_BLC, ns->fw_blc); 144} 145 146/* 147** Read a register from the ns2501. 148** Returns true if successful, false otherwise. 149** If it returns false, it might be wise to enable the 150** DVO with the above function. 151*/ 152static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, uint8_t * ch) 153{ 154 struct ns2501_priv *ns = dvo->dev_priv; 155 device_t adapter = dvo->i2c_bus; 156 u8 out_buf[2]; 157 u8 in_buf[2]; 158 159 struct iic_msg msgs[] = { 160 { 161 .slave = dvo->slave_addr << 1, 162 .flags = 0, 163 .len = 1, 164 .buf = out_buf, 165 }, 166 { 167 .slave = dvo->slave_addr << 1, 168 .flags = I2C_M_RD, 169 .len = 1, 170 .buf = in_buf, 171 } 172 }; 173 174 out_buf[0] = addr; 175 out_buf[1] = 0; 176 177 if (-iicbus_transfer(adapter, msgs, 2) == 0) { 178 *ch = in_buf[0]; 179 return true; 180 } 181 182 if (!ns->quiet) { 183 DRM_DEBUG_KMS 184 ("Unable to read register 0x%02x from %s:0x%02x.\n", addr, 185 device_get_nameunit(adapter), dvo->slave_addr); 186 } 187 188 return false; 189} 190 191/* 192** Write a register to the ns2501. 193** Returns true if successful, false otherwise. 194** If it returns false, it might be wise to enable the 195** DVO with the above function. 196*/ 197static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) 198{ 199 struct ns2501_priv *ns = dvo->dev_priv; 200 device_t adapter = dvo->i2c_bus; 201 uint8_t out_buf[2]; 202 203 struct iic_msg msg = { 204 .slave = dvo->slave_addr << 1, 205 .flags = 0, 206 .len = 2, 207 .buf = out_buf, 208 }; 209 210 out_buf[0] = addr; 211 out_buf[1] = ch; 212 213 if (-iicbus_transfer(adapter, &msg, 1) == 0) { 214 return true; 215 } 216 217 if (!ns->quiet) { 218 DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d\n", 219 addr, device_get_nameunit(adapter), dvo->slave_addr); 220 } 221 222 return false; 223} 224 225/* National Semiconductor 2501 driver for chip on i2c bus 226 * scan for the chip on the bus. 227 * Hope the VBIOS initialized the PLL correctly so we can 228 * talk to it. If not, it will not be seen and not detected. 229 * Bummer! 230 */ 231static bool ns2501_init(struct intel_dvo_device *dvo, 232 device_t adapter) 233{ 234 /* this will detect the NS2501 chip on the specified i2c bus */ 235 struct ns2501_priv *ns; 236 unsigned char ch; 237 238 ns = malloc(sizeof(struct ns2501_priv), DRM_MEM_KMS, M_NOWAIT | M_ZERO); 239 if (ns == NULL) 240 return false; 241 242 dvo->i2c_bus = adapter; 243 dvo->dev_priv = ns; 244 ns->quiet = true; 245 246 if (!ns2501_readb(dvo, NS2501_VID_LO, &ch)) 247 goto out; 248 249 if (ch != (NS2501_VID & 0xff)) { 250 DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n", 251 ch, device_get_nameunit(adapter), dvo->slave_addr); 252 goto out; 253 } 254 255 if (!ns2501_readb(dvo, NS2501_DID_LO, &ch)) 256 goto out; 257 258 if (ch != (NS2501_DID & 0xff)) { 259 DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n", 260 ch, device_get_nameunit(adapter), dvo->slave_addr); 261 goto out; 262 } 263 ns->quiet = false; 264 ns->reg_8_set = 0; 265 ns->reg_8_shadow = 266 NS2501_8_PD | NS2501_8_BPAS | NS2501_8_VEN | NS2501_8_HEN; 267 268 DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n"); 269 return true; 270 271out: 272 free(ns, DRM_MEM_KMS); 273 return false; 274} 275 276static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo) 277{ 278 /* 279 * This is a Laptop display, it doesn't have hotplugging. 280 * Even if not, the detection bit of the 2501 is unreliable as 281 * it only works for some display types. 282 * It is even more unreliable as the PLL must be active for 283 * allowing reading from the chiop. 284 */ 285 return connector_status_connected; 286} 287 288static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo, 289 struct drm_display_mode *mode) 290{ 291 DRM_DEBUG_KMS 292 ("%s: is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n", 293 __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay, 294 mode->vtotal); 295 296 /* 297 * Currently, these are all the modes I have data from. 298 * More might exist. Unclear how to find the native resolution 299 * of the panel in here so we could always accept it 300 * by disabling the scaler. 301 */ 302 if ((mode->hdisplay == 800 && mode->vdisplay == 600) || 303 (mode->hdisplay == 640 && mode->vdisplay == 480) || 304 (mode->hdisplay == 1024 && mode->vdisplay == 768)) { 305 return MODE_OK; 306 } else { 307 return MODE_ONE_SIZE; /* Is this a reasonable error? */ 308 } 309} 310 311static void ns2501_mode_set(struct intel_dvo_device *dvo, 312 struct drm_display_mode *mode, 313 struct drm_display_mode *adjusted_mode) 314{ 315 bool ok; 316 bool restore = false; 317 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); 318 319 DRM_DEBUG_KMS 320 ("%s: set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n", 321 __FUNCTION__, mode->hdisplay, mode->htotal, mode->vdisplay, 322 mode->vtotal); 323 324 /* 325 * Where do I find the native resolution for which scaling is not required??? 326 * 327 * First trigger the DVO on as otherwise the chip does not appear on the i2c 328 * bus. 329 */ 330 do { 331 ok = true; 332 333 if (mode->hdisplay == 800 && mode->vdisplay == 600) { 334 /* mode 277 */ 335 ns->reg_8_shadow &= ~NS2501_8_BPAS; 336 DRM_DEBUG_KMS("%s: switching to 800x600\n", 337 __FUNCTION__); 338 339 /* 340 * No, I do not know where this data comes from. 341 * It is just what the video bios left in the DVO, so 342 * I'm just copying it here over. 343 * This also means that I cannot support any other modes 344 * except the ones supported by the bios. 345 */ 346 ok &= ns2501_writeb(dvo, 0x11, 0xc8); // 0xc7 also works. 347 ok &= ns2501_writeb(dvo, 0x1b, 0x19); 348 ok &= ns2501_writeb(dvo, 0x1c, 0x62); // VBIOS left 0x64 here, but 0x62 works nicer 349 ok &= ns2501_writeb(dvo, 0x1d, 0x02); 350 351 ok &= ns2501_writeb(dvo, 0x34, 0x03); 352 ok &= ns2501_writeb(dvo, 0x35, 0xff); 353 354 ok &= ns2501_writeb(dvo, 0x80, 0x27); 355 ok &= ns2501_writeb(dvo, 0x81, 0x03); 356 ok &= ns2501_writeb(dvo, 0x82, 0x41); 357 ok &= ns2501_writeb(dvo, 0x83, 0x05); 358 359 ok &= ns2501_writeb(dvo, 0x8d, 0x02); 360 ok &= ns2501_writeb(dvo, 0x8e, 0x04); 361 ok &= ns2501_writeb(dvo, 0x8f, 0x00); 362 363 ok &= ns2501_writeb(dvo, 0x90, 0xfe); /* vertical. VBIOS left 0xff here, but 0xfe works better */ 364 ok &= ns2501_writeb(dvo, 0x91, 0x07); 365 ok &= ns2501_writeb(dvo, 0x94, 0x00); 366 ok &= ns2501_writeb(dvo, 0x95, 0x00); 367 368 ok &= ns2501_writeb(dvo, 0x96, 0x00); 369 370 ok &= ns2501_writeb(dvo, 0x99, 0x00); 371 ok &= ns2501_writeb(dvo, 0x9a, 0x88); 372 373 ok &= ns2501_writeb(dvo, 0x9c, 0x23); /* Looks like first and last line of the image. */ 374 ok &= ns2501_writeb(dvo, 0x9d, 0x00); 375 ok &= ns2501_writeb(dvo, 0x9e, 0x25); 376 ok &= ns2501_writeb(dvo, 0x9f, 0x03); 377 378 ok &= ns2501_writeb(dvo, 0xa4, 0x80); 379 380 ok &= ns2501_writeb(dvo, 0xb6, 0x00); 381 382 ok &= ns2501_writeb(dvo, 0xb9, 0xc8); /* horizontal? */ 383 ok &= ns2501_writeb(dvo, 0xba, 0x00); /* horizontal? */ 384 385 ok &= ns2501_writeb(dvo, 0xc0, 0x05); /* horizontal? */ 386 ok &= ns2501_writeb(dvo, 0xc1, 0xd7); 387 388 ok &= ns2501_writeb(dvo, 0xc2, 0x00); 389 ok &= ns2501_writeb(dvo, 0xc3, 0xf8); 390 391 ok &= ns2501_writeb(dvo, 0xc4, 0x03); 392 ok &= ns2501_writeb(dvo, 0xc5, 0x1a); 393 394 ok &= ns2501_writeb(dvo, 0xc6, 0x00); 395 ok &= ns2501_writeb(dvo, 0xc7, 0x73); 396 ok &= ns2501_writeb(dvo, 0xc8, 0x02); 397 398 } else if (mode->hdisplay == 640 && mode->vdisplay == 480) { 399 /* mode 274 */ 400 DRM_DEBUG_KMS("%s: switching to 640x480\n", 401 __FUNCTION__); 402 /* 403 * No, I do not know where this data comes from. 404 * It is just what the video bios left in the DVO, so 405 * I'm just copying it here over. 406 * This also means that I cannot support any other modes 407 * except the ones supported by the bios. 408 */ 409 ns->reg_8_shadow &= ~NS2501_8_BPAS; 410 411 ok &= ns2501_writeb(dvo, 0x11, 0xa0); 412 ok &= ns2501_writeb(dvo, 0x1b, 0x11); 413 ok &= ns2501_writeb(dvo, 0x1c, 0x54); 414 ok &= ns2501_writeb(dvo, 0x1d, 0x03); 415 416 ok &= ns2501_writeb(dvo, 0x34, 0x03); 417 ok &= ns2501_writeb(dvo, 0x35, 0xff); 418 419 ok &= ns2501_writeb(dvo, 0x80, 0xff); 420 ok &= ns2501_writeb(dvo, 0x81, 0x07); 421 ok &= ns2501_writeb(dvo, 0x82, 0x3d); 422 ok &= ns2501_writeb(dvo, 0x83, 0x05); 423 424 ok &= ns2501_writeb(dvo, 0x8d, 0x02); 425 ok &= ns2501_writeb(dvo, 0x8e, 0x10); 426 ok &= ns2501_writeb(dvo, 0x8f, 0x00); 427 428 ok &= ns2501_writeb(dvo, 0x90, 0xff); /* vertical */ 429 ok &= ns2501_writeb(dvo, 0x91, 0x07); 430 ok &= ns2501_writeb(dvo, 0x94, 0x00); 431 ok &= ns2501_writeb(dvo, 0x95, 0x00); 432 433 ok &= ns2501_writeb(dvo, 0x96, 0x05); 434 435 ok &= ns2501_writeb(dvo, 0x99, 0x00); 436 ok &= ns2501_writeb(dvo, 0x9a, 0x88); 437 438 ok &= ns2501_writeb(dvo, 0x9c, 0x24); 439 ok &= ns2501_writeb(dvo, 0x9d, 0x00); 440 ok &= ns2501_writeb(dvo, 0x9e, 0x25); 441 ok &= ns2501_writeb(dvo, 0x9f, 0x03); 442 443 ok &= ns2501_writeb(dvo, 0xa4, 0x84); 444 445 ok &= ns2501_writeb(dvo, 0xb6, 0x09); 446 447 ok &= ns2501_writeb(dvo, 0xb9, 0xa0); /* horizontal? */ 448 ok &= ns2501_writeb(dvo, 0xba, 0x00); /* horizontal? */ 449 450 ok &= ns2501_writeb(dvo, 0xc0, 0x05); /* horizontal? */ 451 ok &= ns2501_writeb(dvo, 0xc1, 0x90); 452 453 ok &= ns2501_writeb(dvo, 0xc2, 0x00); 454 ok &= ns2501_writeb(dvo, 0xc3, 0x0f); 455 456 ok &= ns2501_writeb(dvo, 0xc4, 0x03); 457 ok &= ns2501_writeb(dvo, 0xc5, 0x16); 458 459 ok &= ns2501_writeb(dvo, 0xc6, 0x00); 460 ok &= ns2501_writeb(dvo, 0xc7, 0x02); 461 ok &= ns2501_writeb(dvo, 0xc8, 0x02); 462 463 } else if (mode->hdisplay == 1024 && mode->vdisplay == 768) { 464 /* mode 280 */ 465 DRM_DEBUG_KMS("%s: switching to 1024x768\n", 466 __FUNCTION__); 467 /* 468 * This might or might not work, actually. I'm silently 469 * assuming here that the native panel resolution is 470 * 1024x768. If not, then this leaves the scaler disabled 471 * generating a picture that is likely not the expected. 472 * 473 * Problem is that I do not know where to take the panel 474 * dimensions from. 475 * 476 * Enable the bypass, scaling not required. 477 * 478 * The scaler registers are irrelevant here.... 479 * 480 */ 481 ns->reg_8_shadow |= NS2501_8_BPAS; 482 ok &= ns2501_writeb(dvo, 0x37, 0x44); 483 } else { 484 /* 485 * Data not known. Bummer! 486 * Hopefully, the code should not go here 487 * as mode_OK delivered no other modes. 488 */ 489 ns->reg_8_shadow |= NS2501_8_BPAS; 490 } 491 ok &= ns2501_writeb(dvo, NS2501_REG8, ns->reg_8_shadow); 492 493 if (!ok) { 494 if (restore) 495 restore_dvo(dvo); 496 enable_dvo(dvo); 497 restore = true; 498 } 499 } while (!ok); 500 /* 501 * Restore the old i915 registers before 502 * forcing the ns2501 on. 503 */ 504 if (restore) 505 restore_dvo(dvo); 506} 507 508/* set the NS2501 power state */ 509static bool ns2501_get_hw_state(struct intel_dvo_device *dvo) 510{ 511 unsigned char ch; 512 513 if (!ns2501_readb(dvo, NS2501_REG8, &ch)) 514 return false; 515 516 if (ch & NS2501_8_PD) 517 return true; 518 else 519 return false; 520} 521 522/* set the NS2501 power state */ 523static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable) 524{ 525 bool ok; 526 bool restore = false; 527 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); 528 unsigned char ch; 529 530 DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %i\n", 531 __FUNCTION__, enable); 532 533 ch = ns->reg_8_shadow; 534 535 if (enable) 536 ch |= NS2501_8_PD; 537 else 538 ch &= ~NS2501_8_PD; 539 540 if (ns->reg_8_set == 0 || ns->reg_8_shadow != ch) { 541 ns->reg_8_set = 1; 542 ns->reg_8_shadow = ch; 543 544 do { 545 ok = true; 546 ok &= ns2501_writeb(dvo, NS2501_REG8, ch); 547 ok &= 548 ns2501_writeb(dvo, 0x34, 549 enable ? 0x03 : 0x00); 550 ok &= 551 ns2501_writeb(dvo, 0x35, 552 enable ? 0xff : 0x00); 553 if (!ok) { 554 if (restore) 555 restore_dvo(dvo); 556 enable_dvo(dvo); 557 restore = true; 558 } 559 } while (!ok); 560 561 if (restore) 562 restore_dvo(dvo); 563 } 564} 565 566static void ns2501_dump_regs(struct intel_dvo_device *dvo) 567{ 568 uint8_t val; 569 570 ns2501_readb(dvo, NS2501_FREQ_LO, &val); 571 DRM_LOG_KMS("NS2501_FREQ_LO: 0x%02x\n", val); 572 ns2501_readb(dvo, NS2501_FREQ_HI, &val); 573 DRM_LOG_KMS("NS2501_FREQ_HI: 0x%02x\n", val); 574 ns2501_readb(dvo, NS2501_REG8, &val); 575 DRM_LOG_KMS("NS2501_REG8: 0x%02x\n", val); 576 ns2501_readb(dvo, NS2501_REG9, &val); 577 DRM_LOG_KMS("NS2501_REG9: 0x%02x\n", val); 578 ns2501_readb(dvo, NS2501_REGC, &val); 579 DRM_LOG_KMS("NS2501_REGC: 0x%02x\n", val); 580} 581 582static void ns2501_destroy(struct intel_dvo_device *dvo) 583{ 584 struct ns2501_priv *ns = dvo->dev_priv; 585 586 if (ns) { 587 free(ns, DRM_MEM_KMS); 588 dvo->dev_priv = NULL; 589 } 590} 591 592struct intel_dvo_dev_ops ns2501_ops = { 593 .init = ns2501_init, 594 .detect = ns2501_detect, 595 .mode_valid = ns2501_mode_valid, 596 .mode_set = ns2501_mode_set, 597 .dpms = ns2501_dpms, 598 .get_hw_state = ns2501_get_hw_state, 599 .dump_regs = ns2501_dump_regs, 600 .destroy = ns2501_destroy, 601}; 602