1/* -*- c-basic-offset: 4 -*- */ 2/* 3 * Copyright � 2006 Intel Corporation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 * Authors: 25 * Eric Anholt <eric@anholt.net> 26 * 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include <unistd.h> 34#include <string.h> 35#include <assert.h> 36#include <stdlib.h> 37#include <math.h> 38#include <sys/ioctl.h> 39 40#include "xf86.h" 41#include "i830.h" 42#include "i830_bios.h" 43#include "i830_display.h" 44#include "i830_debug.h" 45#include "xf86Modes.h" 46 47typedef struct { 48 /* given values */ 49 int n; 50 int m1, m2; 51 int p1, p2; 52 /* derived values */ 53 int dot; 54 int vco; 55 int m; 56 int p; 57} intel_clock_t; 58 59typedef struct { 60 int min, max; 61} intel_range_t; 62 63typedef struct { 64 int dot_limit; 65 int p2_slow, p2_fast; 66} intel_p2_t; 67 68#define INTEL_P2_NUM 2 69 70typedef struct intel_limit intel_limit_t; 71struct intel_limit { 72 intel_range_t dot, vco, n, m, m1, m2, p, p1; 73 intel_p2_t p2; 74 Bool (* find_pll)(const intel_limit_t *, xf86CrtcPtr, 75 int, int, intel_clock_t *); 76}; 77 78#define I8XX_DOT_MIN 25000 79#define I8XX_DOT_MAX 350000 80#define I8XX_VCO_MIN 930000 81#define I8XX_VCO_MAX 1400000 82#define I8XX_N_MIN 3 83#define I8XX_N_MAX 16 84#define I8XX_M_MIN 96 85#define I8XX_M_MAX 140 86#define I8XX_M1_MIN 18 87#define I8XX_M1_MAX 26 88#define I8XX_M2_MIN 6 89#define I8XX_M2_MAX 16 90#define I8XX_P_MIN 4 91#define I8XX_P_MAX 128 92#define I8XX_P1_MIN 2 93#define I8XX_P1_MAX 33 94#define I8XX_P1_LVDS_MIN 1 95#define I8XX_P1_LVDS_MAX 6 96#define I8XX_P2_SLOW 4 97#define I8XX_P2_FAST 2 98#define I8XX_P2_LVDS_SLOW 14 99#define I8XX_P2_LVDS_FAST 7 100#define I8XX_P2_SLOW_LIMIT 165000 101 102#define I9XX_DOT_MIN 20000 103#define I9XX_DOT_MAX 400000 104#define I9XX_VCO_MIN 1400000 105#define I9XX_VCO_MAX 2800000 106#define IGD_VCO_MIN 1700000 107#define IGD_VCO_MAX 3500000 108 109/* Haven't found any reason to go this fast, but newer chips support it */ 110#define I96X_VCO_MAX 3200000 111 112/* 113 * These values are taken from the broadwater/crestline PLL spreadsheet. 114 * All of the defines here are for the programmed register value, not 115 * the 'counter' value (e.g. Ncounter = Nregister + 2) 116 */ 117#define I9XX_N_MIN 1 118#define I9XX_N_MAX 6 119/* IGD's Ncounter is a ring counter */ 120#define IGD_N_MIN 3 121#define IGD_N_MAX 6 122#define I9XX_M_MIN 70 123#define I9XX_M_MAX 120 124#define IGD_M_MIN 2 125#define IGD_M_MAX 256 126 127/* these two come from the calm1 macro */ 128#define I9XX_M1_MIN 10 129#define I9XX_M1_MAX 22 130#define I9XX_M2_MIN 5 131#define I9XX_M2_MAX 9 132/* IGD M1 is reserved, and must be 0 */ 133#define IGD_M1_MIN 0 134#define IGD_M1_MAX 0 135#define IGD_M2_MIN 0 136#define IGD_M2_MAX 254 137 138#define I9XX_P_SDVO_DAC_MIN 5 139#define I9XX_P_SDVO_DAC_MAX 80 140#define I9XX_P_LVDS_MIN 7 141#define I9XX_P_LVDS_MAX 98 142#define IGD_P_LVDS_MIN 7 143#define IGD_P_LVDS_MAX 112 144#define I9XX_P1_MIN 1 145#define I9XX_P1_MAX 8 146#define I9XX_P2_SDVO_DAC_SLOW 10 147#define I9XX_P2_SDVO_DAC_FAST 5 148#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000 149#define I9XX_P2_LVDS_SLOW 14 150#define I9XX_P2_LVDS_FAST 7 151#define I9XX_P2_LVDS_SLOW_LIMIT 112000 152 153#define INTEL_LIMIT_I8XX_DVO_DAC 0 154#define INTEL_LIMIT_I8XX_LVDS 1 155#define INTEL_LIMIT_I9XX_SDVO_DAC 2 156#define INTEL_LIMIT_I9XX_LVDS 3 157#define INTEL_LIMIT_IGD_SDVO_DAC 4 158#define INTEL_LIMIT_IGD_LVDS 5 159#define INTEL_LIMIT_G4X_SDVO 6 160#define INTEL_LIMIT_G4X_HDMI_DAC 7 161#define INTEL_LIMIT_G4X_SINGLE_LVDS 8 162#define INTEL_LIMIT_G4X_DUAL_LVDS 9 163 164/*The parameter is for SDVO on G4x platform*/ 165#define G4X_VCO_MIN 1750000 166#define G4X_VCO_MAX 3500000 167#define G4X_DOT_SDVO_MIN 25000 168#define G4X_DOT_SDVO_MAX 270000 169#define G4X_N_SDVO_MIN 1 170#define G4X_N_SDVO_MAX 4 171#define G4X_M_SDVO_MIN 104 172#define G4X_M_SDVO_MAX 138 173#define G4X_M1_SDVO_MIN 17 174#define G4X_M1_SDVO_MAX 23 175#define G4X_M2_SDVO_MIN 5 176#define G4X_M2_SDVO_MAX 11 177#define G4X_P_SDVO_MIN 10 178#define G4X_P_SDVO_MAX 30 179#define G4X_P1_SDVO_MIN 1 180#define G4X_P1_SDVO_MAX 3 181#define G4X_P2_SDVO_SLOW 10 182#define G4X_P2_SDVO_FAST 10 183#define G4X_P2_SDVO_LIMIT 270000 184 185/*The parameter is for HDMI_DAC on G4x platform*/ 186#define G4X_DOT_HDMI_DAC_MIN 22000 187#define G4X_DOT_HDMI_DAC_MAX 400000 188#define G4X_N_HDMI_DAC_MIN 1 189#define G4X_N_HDMI_DAC_MAX 4 190#define G4X_M_HDMI_DAC_MIN 104 191#define G4X_M_HDMI_DAC_MAX 138 192#define G4X_M1_HDMI_DAC_MIN 16 193#define G4X_M1_HDMI_DAC_MAX 23 194#define G4X_M2_HDMI_DAC_MIN 5 195#define G4X_M2_HDMI_DAC_MAX 11 196#define G4X_P_HDMI_DAC_MIN 5 197#define G4X_P_HDMI_DAC_MAX 80 198#define G4X_P1_HDMI_DAC_MIN 1 199#define G4X_P1_HDMI_DAC_MAX 8 200#define G4X_P2_HDMI_DAC_SLOW 10 201#define G4X_P2_HDMI_DAC_FAST 5 202#define G4X_P2_HDMI_DAC_LIMIT 165000 203 204/*The parameter is for SINGLE_LVDS on G4x platform*/ 205#define G4X_DOT_SINGLE_LVDS_MIN 20000 206#define G4X_DOT_SINGLE_LVDS_MAX 115000 207#define G4X_N_SINGLE_LVDS_MIN 1 208#define G4X_N_SINGLE_LVDS_MAX 3 209#define G4X_M_SINGLE_LVDS_MIN 104 210#define G4X_M_SINGLE_LVDS_MAX 138 211#define G4X_M1_SINGLE_LVDS_MIN 17 212#define G4X_M1_SINGLE_LVDS_MAX 23 213#define G4X_M2_SINGLE_LVDS_MIN 5 214#define G4X_M2_SINGLE_LVDS_MAX 11 215#define G4X_P_SINGLE_LVDS_MIN 28 216#define G4X_P_SINGLE_LVDS_MAX 112 217#define G4X_P1_SINGLE_LVDS_MIN 2 218#define G4X_P1_SINGLE_LVDS_MAX 8 219#define G4X_P2_SINGLE_LVDS_SLOW 14 220#define G4X_P2_SINGLE_LVDS_FAST 14 221#define G4X_P2_SINGLE_LVDS_LIMIT 0 222 223/*The parameter is for DUAL_LVDS on G4x platform*/ 224#define G4X_DOT_DUAL_LVDS_MIN 80000 225#define G4X_DOT_DUAL_LVDS_MAX 224000 226#define G4X_N_DUAL_LVDS_MIN 1 227#define G4X_N_DUAL_LVDS_MAX 3 228#define G4X_M_DUAL_LVDS_MIN 104 229#define G4X_M_DUAL_LVDS_MAX 138 230#define G4X_M1_DUAL_LVDS_MIN 17 231#define G4X_M1_DUAL_LVDS_MAX 23 232#define G4X_M2_DUAL_LVDS_MIN 5 233#define G4X_M2_DUAL_LVDS_MAX 11 234#define G4X_P_DUAL_LVDS_MIN 14 235#define G4X_P_DUAL_LVDS_MAX 42 236#define G4X_P1_DUAL_LVDS_MIN 2 237#define G4X_P1_DUAL_LVDS_MAX 6 238#define G4X_P2_DUAL_LVDS_SLOW 7 239#define G4X_P2_DUAL_LVDS_FAST 7 240#define G4X_P2_DUAL_LVDS_LIMIT 0 241 242static Bool 243intel_find_pll_i8xx_and_i9xx(const intel_limit_t *, xf86CrtcPtr, 244 int, int, intel_clock_t *); 245static Bool 246intel_find_pll_g4x(const intel_limit_t *, xf86CrtcPtr, 247 int, int, intel_clock_t *); 248static void 249i830_crtc_load_lut(xf86CrtcPtr crtc); 250 251static const intel_limit_t intel_limits[] = { 252 { /* INTEL_LIMIT_I8XX_DVO_DAC */ 253 .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, 254 .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, 255 .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, 256 .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX }, 257 .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX }, 258 .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX }, 259 .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX }, 260 .p1 = { .min = I8XX_P1_MIN, .max = I8XX_P1_MAX }, 261 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 262 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, 263 .find_pll = intel_find_pll_i8xx_and_i9xx, 264 }, 265 { /* INTEL_LIMIT_I8XX_LVDS */ 266 .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, 267 .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, 268 .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, 269 .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX }, 270 .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX }, 271 .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX }, 272 .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX }, 273 .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX }, 274 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 275 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, 276 .find_pll = intel_find_pll_i8xx_and_i9xx, 277 }, 278 { /* INTEL_LIMIT_I9XX_SDVO_DAC */ 279 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, 280 .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, 281 .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, 282 .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX }, 283 .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX }, 284 .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX }, 285 .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX }, 286 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, 287 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 288 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 289 .find_pll = intel_find_pll_i8xx_and_i9xx, 290 }, 291 { /* INTEL_LIMIT_I9XX_LVDS */ 292 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, 293 .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, 294 .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, 295 .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX }, 296 .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX }, 297 .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX }, 298 .p = { .min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX }, 299 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, 300 /* The single-channel range is 25-112Mhz, and dual-channel 301 * is 80-224Mhz. Prefer single channel as much as possible. 302 */ 303 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 304 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, 305 .find_pll = intel_find_pll_i8xx_and_i9xx, 306 }, 307 { /* INTEL_LIMIT_IGD_SDVO */ 308 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, 309 .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, 310 .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, 311 .m = { .min = IGD_M_MIN, .max = IGD_M_MAX }, 312 .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX }, 313 .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX }, 314 .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX }, 315 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, 316 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 317 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 318 .find_pll = intel_find_pll_i8xx_and_i9xx, 319 }, 320 { /* INTEL_LIMIT_IGD_LVDS */ 321 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, 322 .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, 323 .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, 324 .m = { .min = IGD_M_MIN, .max = IGD_M_MAX }, 325 .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX }, 326 .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX }, 327 .p = { .min = IGD_P_LVDS_MIN, .max = IGD_P_LVDS_MAX }, 328 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, 329 /* IGD only supports single-channel mode. */ 330 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 331 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, 332 .find_pll = intel_find_pll_i8xx_and_i9xx, 333 }, 334 /* below parameter and function is for G4X Chipset Family*/ 335 { /* INTEL_LIMIT_G4X_SDVO */ 336 .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, 337 .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, 338 .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, 339 .m = { .min = G4X_M_SDVO_MIN, .max = G4X_M_SDVO_MAX }, 340 .m1 = { .min = G4X_M1_SDVO_MIN, .max = G4X_M1_SDVO_MAX }, 341 .m2 = { .min = G4X_M2_SDVO_MIN, .max = G4X_M2_SDVO_MAX }, 342 .p = { .min = G4X_P_SDVO_MIN, .max = G4X_P_SDVO_MAX }, 343 .p1 = { .min = G4X_P1_SDVO_MIN, .max = G4X_P1_SDVO_MAX}, 344 .p2 = { .dot_limit = G4X_P2_SDVO_LIMIT, 345 .p2_slow = G4X_P2_SDVO_SLOW, 346 .p2_fast = G4X_P2_SDVO_FAST }, 347 .find_pll = intel_find_pll_g4x, 348 }, 349 { /* INTEL_LIMIT_G4X_HDMI_DAC */ 350 .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, 351 .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, 352 .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, 353 .m = { .min = G4X_M_HDMI_DAC_MIN, .max = G4X_M_HDMI_DAC_MAX }, 354 .m1 = { .min = G4X_M1_HDMI_DAC_MIN, .max = G4X_M1_HDMI_DAC_MAX }, 355 .m2 = { .min = G4X_M2_HDMI_DAC_MIN, .max = G4X_M2_HDMI_DAC_MAX }, 356 .p = { .min = G4X_P_HDMI_DAC_MIN, .max = G4X_P_HDMI_DAC_MAX }, 357 .p1 = { .min = G4X_P1_HDMI_DAC_MIN, .max = G4X_P1_HDMI_DAC_MAX}, 358 .p2 = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT, 359 .p2_slow = G4X_P2_HDMI_DAC_SLOW, 360 .p2_fast = G4X_P2_HDMI_DAC_FAST }, 361 .find_pll = intel_find_pll_g4x, 362 }, 363 { /* INTEL_LIMIT_G4X_SINGLE_LVDS */ 364 .dot = { .min = G4X_DOT_SINGLE_LVDS_MIN, 365 .max = G4X_DOT_SINGLE_LVDS_MAX }, 366 .vco = { .min = G4X_VCO_MIN, 367 .max = G4X_VCO_MAX }, 368 .n = { .min = G4X_N_SINGLE_LVDS_MIN, 369 .max = G4X_N_SINGLE_LVDS_MAX }, 370 .m = { .min = G4X_M_SINGLE_LVDS_MIN, 371 .max = G4X_M_SINGLE_LVDS_MAX }, 372 .m1 = { .min = G4X_M1_SINGLE_LVDS_MIN, 373 .max = G4X_M1_SINGLE_LVDS_MAX }, 374 .m2 = { .min = G4X_M2_SINGLE_LVDS_MIN, 375 .max = G4X_M2_SINGLE_LVDS_MAX }, 376 .p = { .min = G4X_P_SINGLE_LVDS_MIN, 377 .max = G4X_P_SINGLE_LVDS_MAX }, 378 .p1 = { .min = G4X_P1_SINGLE_LVDS_MIN, 379 .max = G4X_P1_SINGLE_LVDS_MAX }, 380 .p2 = { .dot_limit = G4X_P2_SINGLE_LVDS_LIMIT, 381 .p2_slow = G4X_P2_SINGLE_LVDS_SLOW, 382 .p2_fast = G4X_P2_SINGLE_LVDS_FAST }, 383 .find_pll = intel_find_pll_g4x, 384 }, 385 { /* INTEL_LIMIT_G4X_DUAL_LVDS */ 386 .dot = { .min = G4X_DOT_DUAL_LVDS_MIN, 387 .max = G4X_DOT_DUAL_LVDS_MAX }, 388 .vco = { .min = G4X_VCO_MIN, 389 .max = G4X_VCO_MAX}, 390 .n = { .min = G4X_N_DUAL_LVDS_MIN, 391 .max = G4X_N_DUAL_LVDS_MAX }, 392 .m = { .min = G4X_M_DUAL_LVDS_MIN, 393 .max = G4X_M_DUAL_LVDS_MAX }, 394 .m1 = { .min = G4X_M1_DUAL_LVDS_MIN, 395 .max = G4X_M1_DUAL_LVDS_MAX }, 396 .m2 = { .min = G4X_M2_DUAL_LVDS_MIN, 397 .max = G4X_M2_DUAL_LVDS_MAX }, 398 .p = { .min = G4X_P_DUAL_LVDS_MIN, 399 .max = G4X_P_DUAL_LVDS_MAX }, 400 .p1 = { .min = G4X_P1_DUAL_LVDS_MIN, 401 .max = G4X_P1_DUAL_LVDS_MAX}, 402 .p2 = { .dot_limit = G4X_P2_DUAL_LVDS_LIMIT, 403 .p2_slow = G4X_P2_DUAL_LVDS_SLOW, 404 .p2_fast = G4X_P2_DUAL_LVDS_FAST }, 405 .find_pll = intel_find_pll_g4x, 406 }, 407}; 408 409static const intel_limit_t *intel_limit_g4x (xf86CrtcPtr crtc) 410{ 411 ScrnInfoPtr pScrn = crtc->scrn; 412 I830Ptr pI830 = I830PTR(pScrn); 413 const intel_limit_t *limit; 414 415 if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) { 416 if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) { 417 /* LVDS with dual channel */ 418 limit = &intel_limits[INTEL_LIMIT_G4X_DUAL_LVDS]; 419 } else /* LVDS with single channel */ 420 limit = &intel_limits[INTEL_LIMIT_G4X_SINGLE_LVDS]; 421 } else if (i830PipeHasType (crtc, I830_OUTPUT_HDMI) || 422 i830PipeHasType (crtc, I830_OUTPUT_ANALOG)) { 423 limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC]; 424 } else if (i830PipeHasType (crtc, I830_OUTPUT_SDVO)) { 425 limit = &intel_limits[INTEL_LIMIT_G4X_SDVO]; 426 } else /* The option is for other outputs */ 427 limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; 428 return limit; 429} 430 431static const intel_limit_t *intel_limit (xf86CrtcPtr crtc) 432{ 433 ScrnInfoPtr pScrn = crtc->scrn; 434 I830Ptr pI830 = I830PTR(pScrn); 435 const intel_limit_t *limit; 436 437 if (IS_G4X(pI830)) { 438 limit = intel_limit_g4x(crtc); 439 } else if (IS_I9XX(pI830) && !IS_IGD(pI830)) { 440 if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) 441 limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; 442 else 443 limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; 444 } else if (IS_IGD(pI830)) { 445 if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) 446 limit = &intel_limits[INTEL_LIMIT_IGD_LVDS]; 447 else 448 limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC]; 449 } else { 450 if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) 451 limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; 452 else 453 limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; 454 } 455 456 return limit; 457} 458 459/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ 460 461static void i8xx_clock(int refclk, intel_clock_t *clock) 462{ 463 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); 464 clock->p = clock->p1 * clock->p2; 465 clock->vco = refclk * clock->m / (clock->n + 2); 466 clock->dot = clock->vco / clock->p; 467} 468 469/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ 470 471static void i9xx_clock(int refclk, intel_clock_t *clock) 472{ 473 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); 474 clock->p = clock->p1 * clock->p2; 475 clock->vco = refclk * clock->m / (clock->n + 2); 476 clock->dot = clock->vco / clock->p; 477} 478 479/* m1 is reserved as 0 in IGD, n is a ring counter */ 480static void igd_clock(int refclk, intel_clock_t *clock) 481{ 482 clock->m = clock->m2 + 2; 483 clock->p = clock->p1 * clock->p2; 484 clock->vco = refclk * clock->m / clock->n; 485 clock->dot = clock->vco / clock->p; 486} 487 488static void intel_clock(I830Ptr pI830, int refclk, intel_clock_t *clock) 489{ 490 if (IS_I9XX(pI830)) { 491 if (IS_IGD(pI830)) 492 igd_clock(refclk, clock); 493 else 494 i9xx_clock (refclk, clock); 495 } else 496 i8xx_clock (refclk, clock); 497} 498 499static void 500i830PrintPll(ScrnInfoPtr pScrn, char *prefix, intel_clock_t *clock) 501{ 502 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 503 "%s: dotclock %d vco %d ((m %d, m1 %d, m2 %d), n %d, " 504 "(p %d, p1 %d, p2 %d))\n", 505 prefix, clock->dot, clock->vco, 506 clock->m, clock->m1, clock->m2, 507 clock->n, 508 clock->p, clock->p1, clock->p2); 509} 510 511/** 512 * Returns whether any output on the specified pipe is of the specified type 513 */ 514Bool 515i830PipeHasType (xf86CrtcPtr crtc, int type) 516{ 517 ScrnInfoPtr pScrn = crtc->scrn; 518 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 519 int i; 520 521 for (i = 0; i < xf86_config->num_output; i++) 522 { 523 xf86OutputPtr output = xf86_config->output[i]; 524 if (output->crtc == crtc) 525 { 526 I830OutputPrivatePtr intel_output = output->driver_private; 527 if (intel_output->type == type) 528 return TRUE; 529 } 530 } 531 return FALSE; 532} 533 534#define i830PllInvalid(s) { /* ErrorF (s) */; return FALSE; } 535/** 536 * Returns whether the given set of divisors are valid for a given refclk with 537 * the given outputs. 538 */ 539 540static Bool 541i830PllIsValid(xf86CrtcPtr crtc, intel_clock_t *clock) 542{ 543 const intel_limit_t *limit = intel_limit (crtc); 544 ScrnInfoPtr pScrn = crtc->scrn; 545 I830Ptr pI830 = I830PTR(pScrn); 546 547 if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) 548 i830PllInvalid ("p1 out of range\n"); 549 if (clock->p < limit->p.min || limit->p.max < clock->p) 550 i830PllInvalid ("p out of range\n"); 551 if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2) 552 i830PllInvalid ("m2 out of range\n"); 553 if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) 554 i830PllInvalid ("m1 out of range\n"); 555 if (clock->m1 <= clock->m2 && !IS_IGD(pI830)) 556 i830PllInvalid ("m1 <= m2\n"); 557 if (clock->m < limit->m.min || limit->m.max < clock->m) 558 i830PllInvalid ("m out of range\n"); 559 if (clock->n < limit->n.min || limit->n.max < clock->n) 560 i830PllInvalid ("n out of range\n"); 561 if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) 562 i830PllInvalid ("vco out of range\n"); 563 /* XXX: We may need to be checking "Dot clock" depending on the multiplier, 564 * output, etc., rather than just a single range. 565 */ 566 if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) 567 i830PllInvalid ("dot out of range\n"); 568 569 return TRUE; 570} 571 572static Bool 573intel_find_pll_i8xx_and_i9xx(const intel_limit_t * limit, xf86CrtcPtr crtc, 574 int target, int refclk, intel_clock_t *best_clock) 575{ 576 ScrnInfoPtr pScrn = crtc->scrn; 577 I830Ptr pI830 = I830PTR(pScrn); 578 intel_clock_t clock; 579 int err = target; 580 581 if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) 582 { 583 /* For LVDS, if the panel is on, just rely on its current settings for 584 * dual-channel. We haven't figured out how to reliably set up 585 * different single/dual channel state, if we even can. 586 */ 587 if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) 588 clock.p2 = limit->p2.p2_fast; 589 else 590 clock.p2 = limit->p2.p2_slow; 591 } else { 592 if (target < limit->p2.dot_limit) 593 clock.p2 = limit->p2.p2_slow; 594 else 595 clock.p2 = limit->p2.p2_fast; 596 } 597 598 memset (best_clock, 0, sizeof (*best_clock)); 599 600 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) 601 { 602 for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) 603 { 604 /* m1 is always 0 in IGD */ 605 if (clock.m2 >= clock.m1 && !IS_IGD(pI830)) 606 break; 607 for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) 608 { 609 for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; clock.p1++) 610 { 611 int this_err; 612 613 intel_clock (pI830, refclk, &clock); 614 615 if (!i830PllIsValid(crtc, &clock)) 616 continue; 617 618 this_err = abs(clock.dot - target); 619 if (this_err < err) { 620 *best_clock = clock; 621 err = this_err; 622 } 623 } 624 } 625 } 626 } 627 return (err != target); 628} 629 630static Bool 631intel_find_pll_g4x(const intel_limit_t * limit, xf86CrtcPtr crtc, 632 int target, int refclk, intel_clock_t *best_clock) 633{ 634 ScrnInfoPtr pScrn = crtc->scrn; 635 I830Ptr pI830 = I830PTR(pScrn); 636 intel_clock_t clock; 637 int max_n; 638 Bool found = FALSE; 639 int err_most = target * 0.0048; 640 641 if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) 642 { 643 /* For LVDS, if the panel is on, just rely on its current settings for 644 * dual-channel. We haven't figured out how to reliably set up 645 * different single/dual channel state, if we even can. 646 */ 647 if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) 648 clock.p2 = limit->p2.p2_fast; 649 else 650 clock.p2 = limit->p2.p2_slow; 651 } else { 652 if (target < limit->p2.dot_limit) 653 clock.p2 = limit->p2.p2_slow; 654 else 655 clock.p2 = limit->p2.p2_fast; 656 } 657 658 max_n = limit->n.max; 659 /* based on hardware requirement prefer smaller n to precision */ 660 for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { 661 /* based on hardware requirement prefere larger m1,m2, p1*/ 662 for (clock.m1 = limit->m1.max; 663 clock.m1 >= limit->m1.min; clock.m1--) { 664 for (clock.m2 = limit->m2.max; 665 clock.m2 >= limit->m2.min; clock.m2--) { 666 for (clock.p1 = limit->p1.max; 667 clock.p1 >= limit->p1.min; clock.p1--) { 668 int this_err; 669 670 intel_clock (pI830, refclk, &clock); 671 if (!i830PllIsValid(crtc, &clock)) 672 continue; 673 this_err = abs(clock.dot - target) ; 674 if (this_err < err_most) { 675 memcpy(best_clock, &clock, sizeof(intel_clock_t)); 676 err_most = this_err; 677 /* prefer smaller n to precision */ 678 max_n = clock.n; 679 found = TRUE; 680 } 681 } 682 } 683 } 684 } 685 return found; 686} 687 688void 689i830WaitForVblank(ScrnInfoPtr pScreen) 690{ 691 /* Wait for 20ms, i.e. one cycle at 50hz. */ 692 usleep(30000); 693} 694 695void 696i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) 697{ 698 ScrnInfoPtr pScrn = crtc->scrn; 699 I830Ptr pI830 = I830PTR(pScrn); 700 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 701 int plane = intel_crtc->plane; 702 unsigned long Start, Offset, Stride; 703 int dspbase = (plane == 0 ? DSPABASE : DSPBBASE); 704 int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF); 705 int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF); 706 int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; 707 708 Offset = ((y * pScrn->displayWidth + x) * pI830->cpp); 709 Stride = pScrn->displayWidth * pI830->cpp; 710 if (pI830->front_buffer == NULL) { 711 /* During startup we may be called as part of monitor detection while 712 * there is no memory allocation done, so just supply a dummy base 713 * address. 714 */ 715 Start = 0; 716 } else if (crtc->rotatedData != NULL) { 717 /* offset is done by shadow painting code, not here */ 718 Start = (char *)crtc->rotatedData - (char *)pI830->FbBase; 719 Offset = 0; 720 Stride = intel_crtc->rotate_mem->pitch; 721 } else { 722 Start = pI830->front_buffer->offset; 723 } 724 725 crtc->x = x; 726 crtc->y = y; 727 728 OUTREG(dspstride, Stride); 729 if (IS_I965G(pI830)) { 730 OUTREG(dspbase, Offset); 731 POSTING_READ(dspbase); 732 OUTREG(dspsurf, Start); 733 POSTING_READ(dspsurf); 734 OUTREG(dsptileoff, (y << 16) | x); 735 } else { 736 OUTREG(dspbase, Start + Offset); 737 POSTING_READ(dspbase); 738 } 739} 740 741/* 742 * Both crtc activation and video overlay enablement on pipe B 743 * will fail on i830 if pipe A is not running. This function 744 * makes sure pipe A is active for these cases 745 */ 746 747int 748i830_crtc_pipe (xf86CrtcPtr crtc) 749{ 750 if (crtc == NULL) 751 return 0; 752 return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe; 753} 754 755static xf86CrtcPtr 756i830_crtc_for_pipe (ScrnInfoPtr scrn, int pipe) 757{ 758 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 759 int c; 760 761 for (c = 0; c < xf86_config->num_crtc; c++) 762 { 763 xf86CrtcPtr crtc = xf86_config->crtc[c]; 764 if (i830_crtc_pipe (crtc) == pipe) 765 return crtc; 766 } 767 return NULL; 768} 769 770Bool 771i830_pipe_a_require_activate (ScrnInfoPtr scrn) 772{ 773 xf86CrtcPtr crtc = i830_crtc_for_pipe (scrn, 0); 774 /* VESA 640x480x72Hz mode to set on the pipe */ 775 static DisplayModeRec mode = { 776 NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT, 777 31500, 778 640, 664, 704, 832, 0, 779 480, 489, 491, 520, 0, 780 V_NHSYNC | V_NVSYNC, 781 0, 0, 782 0, 0, 0, 0, 0, 0, 0, 783 0, 0, 0, 0, 0, 0, 784 FALSE, FALSE, 0, NULL, 0, 0.0, 0.0 785 }; 786 787 if (!crtc) 788 return FALSE; 789 if (crtc->enabled) 790 return FALSE; 791 xf86SetModeCrtc (&mode, INTERLACE_HALVE_V); 792 crtc->funcs->mode_set (crtc, &mode, &mode, 0, 0); 793 crtc->funcs->dpms (crtc, DPMSModeOn); 794 return TRUE; 795} 796 797void 798i830_pipe_a_require_deactivate (ScrnInfoPtr scrn) 799{ 800 xf86CrtcPtr crtc = i830_crtc_for_pipe (scrn, 0); 801 802 if (!crtc) 803 return; 804 if (crtc->enabled) 805 return; 806 crtc->funcs->dpms (crtc, DPMSModeOff); 807 return; 808} 809 810/* FIXME: use pixmap private instead if possible */ 811static Bool 812i830_display_tiled(xf86CrtcPtr crtc) 813{ 814 ScrnInfoPtr pScrn = crtc->scrn; 815 I830Ptr pI830 = I830PTR(pScrn); 816 817 /* Rotated data is currently linear, allocated either via XAA or EXA */ 818 if (crtc->rotatedData) 819 return FALSE; 820 821 if (pI830->front_buffer && pI830->front_buffer->tiling != TILE_NONE) 822 return TRUE; 823 824 return FALSE; 825} 826 827/* 828 * Several restrictions: 829 * - DSP[AB]CNTR - no line duplication && no pixel multiplier 830 * - pixel format == 15 bit, 16 bit, or 32 bit xRGB_8888 831 * - no alpha buffer discard 832 * - no dual wide display 833 * - progressive mode only (DSP[AB]CNTR) 834 * - uncompressed fb is <= 2048 in width, 0 mod 8 835 * - uncompressed fb is <= 1536 in height, 0 mod 2 836 * - SR display watermarks must be equal between 16bpp and 32bpp? 837 * 838 * FIXME: verify above conditions are true 839 * 840 * Enable 8xx style FB compression 841 */ 842static void 843i830_enable_fb_compression_8xx(xf86CrtcPtr crtc) 844{ 845 ScrnInfoPtr pScrn = crtc->scrn; 846 I830Ptr pI830 = I830PTR(pScrn); 847 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 848 uint32_t fbc_ctl = 0; 849 unsigned long compressed_stride; 850 int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); 851 unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp; 852 unsigned long interval = 1000; 853 854 if (INREG(FBC_CONTROL) & FBC_CTL_EN) 855 return; 856 857 compressed_stride = pI830->compressed_front_buffer->size / 858 FBC_LL_SIZE; 859 860 if (uncompressed_stride < compressed_stride) 861 compressed_stride = uncompressed_stride; 862 863 /* FBC_CTL wants 64B units */ 864 compressed_stride = (compressed_stride / 64) - 1; 865 866 /* Set it up... */ 867 /* Wait for compressing bit to clear */ 868 while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING) 869 ; /* nothing */ 870 i830WaitForVblank(pScrn); 871 OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr); 872 OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6); 873 OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | 874 FBC_CTL_CPU_FENCE | plane); 875 OUTREG(FBC_FENCE_OFF, crtc->y); 876 877 /* Zero buffers */ 878 memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0, 879 pI830->compressed_front_buffer->size); 880 memset(pI830->FbBase + pI830->compressed_ll_buffer->offset, 0, 881 pI830->compressed_ll_buffer->size); 882 883 /* enable it... */ 884 fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC; 885 fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT; 886 fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; 887 fbc_ctl |= FBC_CTL_UNCOMPRESSIBLE; 888 fbc_ctl |= pI830->front_buffer->fence_nr; 889 OUTREG(FBC_CONTROL, fbc_ctl); 890} 891 892/* 893 * Disable 8xx style FB compression 894 */ 895static void 896i830_disable_fb_compression_8xx(xf86CrtcPtr crtc) 897{ 898 ScrnInfoPtr pScrn = crtc->scrn; 899 I830Ptr pI830 = I830PTR(pScrn); 900 uint32_t fbc_ctl; 901 902 /* Disable compression */ 903 fbc_ctl = INREG(FBC_CONTROL); 904 fbc_ctl &= ~FBC_CTL_EN; 905 OUTREG(FBC_CONTROL, fbc_ctl); 906 907 /* Wait for compressing bit to clear */ 908 while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING) 909 ; /* nothing */ 910} 911 912static void 913i830_disable_fb_compression2(xf86CrtcPtr crtc) 914{ 915 ScrnInfoPtr pScrn = crtc->scrn; 916 I830Ptr pI830 = I830PTR(pScrn); 917 uint32_t dpfc_ctl; 918 919 /* Disable compression */ 920 dpfc_ctl = INREG(DPFC_CONTROL); 921 dpfc_ctl &= ~DPFC_CTL_EN; 922 OUTREG(DPFC_CONTROL, dpfc_ctl); 923 i830WaitForVblank(pScrn); 924} 925 926static void 927i830_enable_fb_compression2(xf86CrtcPtr crtc) 928{ 929 ScrnInfoPtr pScrn = crtc->scrn; 930 I830Ptr pI830 = I830PTR(pScrn); 931 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 932 int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB); 933 unsigned long stall_watermark = 200, frames = 50; 934 935 if (INREG(DPFC_CONTROL) & DPFC_CTL_EN) 936 return; 937 938 /* Set it up... */ 939 i830_disable_fb_compression2(crtc); 940 OUTREG(DPFC_CB_BASE, pI830->compressed_front_buffer->offset); 941 /* Update i830_memory.c too if compression ratio changes */ 942 OUTREG(DPFC_CONTROL, plane | DPFC_CTL_FENCE_EN | DPFC_CTL_LIMIT_4X | 943 pI830->front_buffer->fence_nr); 944 OUTREG(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | 945 (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | 946 (frames << DPFC_RECOMP_TIMER_COUNT_SHIFT)); 947 OUTREG(DPFC_FENCE_YOFF, crtc->y); 948 949 /* Zero buffers */ 950 memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0, 951 pI830->compressed_front_buffer->size); 952 953 /* enable it... */ 954 OUTREG(DPFC_CONTROL, INREG(DPFC_CONTROL) | DPFC_CTL_EN); 955} 956 957static void 958i830_enable_fb_compression(xf86CrtcPtr crtc) 959{ 960 ScrnInfoPtr pScrn = crtc->scrn; 961 I830Ptr pI830 = I830PTR(pScrn); 962 963 if (IS_GM45(pI830)) 964 return i830_enable_fb_compression2(crtc); 965 966 i830_enable_fb_compression_8xx(crtc); 967} 968 969static void 970i830_disable_fb_compression(xf86CrtcPtr crtc) 971{ 972 ScrnInfoPtr pScrn = crtc->scrn; 973 I830Ptr pI830 = I830PTR(pScrn); 974 975 if (IS_GM45(pI830)) 976 return i830_disable_fb_compression2(crtc); 977 978 i830_disable_fb_compression_8xx(crtc); 979} 980 981static Bool 982i830_use_fb_compression(xf86CrtcPtr crtc) 983{ 984 ScrnInfoPtr pScrn = crtc->scrn; 985 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 986 I830Ptr pI830 = I830PTR(pScrn); 987 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 988 unsigned long uncompressed_size; 989 int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); 990 int i, count = 0; 991 992 /* Only available on one pipe at a time */ 993 for (i = 0; i < xf86_config->num_crtc; i++) { 994 if (xf86_config->crtc[i]->enabled) 995 count++; 996 } 997 998 /* Here we disable it to catch one->two pipe enabled configs */ 999 if (count > 1) { 1000 if (i830_fb_compression_supported(pI830)) 1001 i830_disable_fb_compression(crtc); 1002 return FALSE; 1003 } 1004 1005 if (!pI830->fb_compression) 1006 return FALSE; 1007 1008 if (!i830_display_tiled(crtc)) 1009 return FALSE; 1010 1011 /* Pre-965 only supports plane A */ 1012 if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA) 1013 return FALSE; 1014 1015 /* Need 15, 16, or 32 (w/alpha) pixel format */ 1016 if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */ 1017 pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */ 1018 return FALSE; 1019 1020 /* Can't cache more lines than we can track */ 1021 if (crtc->mode.VDisplay > FBC_LL_SIZE) 1022 return FALSE; 1023 1024 /* 1025 * Make sure the compressor doesn't go past the end of our compressed 1026 * buffer if the uncompressed size is large. 1027 */ 1028 uncompressed_size = crtc->mode.HDisplay * crtc->mode.VDisplay * 1029 pI830->cpp; 1030 if (pI830->compressed_front_buffer->size < uncompressed_size) 1031 return FALSE; 1032 1033 /* 1034 * No checks for pixel multiply, incl. horizontal, or interlaced modes 1035 * since they're currently unused. 1036 */ 1037 return TRUE; 1038} 1039 1040#if defined(DRM_IOCTL_MODESET_CTL) 1041static void i830_modeset_ctl(xf86CrtcPtr crtc, int pre) 1042{ 1043 ScrnInfoPtr pScrn = crtc->scrn; 1044 I830Ptr pI830 = I830PTR(pScrn); 1045 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1046 struct drm_modeset_ctl modeset; 1047 1048 if (pI830->directRenderingType <= DRI_NONE) 1049 return; 1050 1051 modeset.crtc = intel_crtc->pipe; 1052 1053 /* 1054 * DPMS will be called many times (especially off), but we only 1055 * want to catch the transition from on->off and off->on. 1056 */ 1057 if (pre && intel_crtc->dpms_mode != DPMSModeOff) { 1058 /* On -> off is a pre modeset */ 1059 modeset.cmd = _DRM_PRE_MODESET; 1060 ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset); 1061 } else if (!pre && intel_crtc->dpms_mode == DPMSModeOff) { 1062 /* Off -> on means post modeset */ 1063 modeset.cmd = _DRM_POST_MODESET; 1064 ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset); 1065 } 1066} 1067#else 1068static void i830_modeset_ctl(xf86CrtcPtr crtc, int dpms_state) 1069{ 1070 return; 1071} 1072#endif /* DRM_IOCTL_MODESET_CTL */ 1073 1074static void 1075i830_disable_vga_plane (xf86CrtcPtr crtc) 1076{ 1077 ScrnInfoPtr pScrn = crtc->scrn; 1078 I830Ptr pI830 = I830PTR(pScrn); 1079 uint8_t sr01; 1080 1081 /* 1082 * Bug #17235: G4X machine needs following steps 1083 * for disable VGA. 1084 * - set bit 5 of SR01; 1085 * - Wait 30us; 1086 * - disable vga plane; 1087 * - restore SR01; 1088 */ 1089 if (IS_G4X(pI830)) { 1090 OUTREG8(SRX, 1); 1091 sr01 = INREG8(SRX + 1); 1092 OUTREG8(SRX + 1, sr01 | (1 << 5)); 1093 usleep(30); 1094 } 1095 1096 OUTREG(VGACNTRL, VGA_DISP_DISABLE); 1097 i830WaitForVblank(pScrn); 1098 1099 /* restore SR01 */ 1100 if (IS_G4X(pI830)) { 1101 OUTREG8(SRX, 1); 1102 OUTREG8(SRX + 1, sr01); 1103 } 1104} 1105 1106static void 1107i830_crtc_enable(xf86CrtcPtr crtc) 1108{ 1109 ScrnInfoPtr pScrn = crtc->scrn; 1110 I830Ptr pI830 = I830PTR(pScrn); 1111 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1112 int pipe = intel_crtc->pipe; 1113 int plane = intel_crtc->plane; 1114 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; 1115 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; 1116 int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; 1117 int dspbase_reg = (plane == 0) ? DSPABASE : DSPBBASE; 1118 uint32_t temp; 1119 1120 /* Enable the DPLL */ 1121 temp = INREG(dpll_reg); 1122 if ((temp & DPLL_VCO_ENABLE) == 0) 1123 { 1124 OUTREG(dpll_reg, temp); 1125 POSTING_READ(dpll_reg); 1126 /* Wait for the clocks to stabilize. */ 1127 usleep(150); 1128 OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE); 1129 POSTING_READ(dpll_reg); 1130 /* Wait for the clocks to stabilize. */ 1131 usleep(150); 1132 OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE); 1133 POSTING_READ(dpll_reg); 1134 /* Wait for the clocks to stabilize. */ 1135 usleep(150); 1136 } 1137 1138 /* Enable the pipe */ 1139 temp = INREG(pipeconf_reg); 1140 if ((temp & PIPEACONF_ENABLE) == 0) 1141 OUTREG(pipeconf_reg, temp | PIPEACONF_ENABLE); 1142 1143 /* Enable the plane */ 1144 temp = INREG(dspcntr_reg); 1145 if ((temp & DISPLAY_PLANE_ENABLE) == 0) 1146 { 1147 OUTREG(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); 1148 /* Flush the plane changes */ 1149 OUTREG(dspbase_reg, INREG(dspbase_reg)); 1150 } 1151 1152 i830_crtc_load_lut(crtc); 1153 1154 /* Give the overlay scaler a chance to enable if it's on this pipe */ 1155 i830_crtc_dpms_video(crtc, TRUE); 1156 1157 /* Reenable compression if needed */ 1158 if (i830_use_fb_compression(crtc)) 1159 i830_enable_fb_compression(crtc); 1160 i830_modeset_ctl(crtc, 0); 1161} 1162 1163void 1164i830_crtc_disable(xf86CrtcPtr crtc, Bool disable_pipe) 1165{ 1166 ScrnInfoPtr pScrn = crtc->scrn; 1167 I830Ptr pI830 = I830PTR(pScrn); 1168 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1169 int pipe = intel_crtc->pipe; 1170 int plane = intel_crtc->plane; 1171 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; 1172 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; 1173 int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; 1174 int dspbase_reg = (plane == 0) ? DSPABASE : DSPBBASE; 1175 uint32_t temp; 1176 1177 i830_modeset_ctl(crtc, 1); 1178 /* Shut off compression if in use */ 1179 if (i830_use_fb_compression(crtc)) 1180 i830_disable_fb_compression(crtc); 1181 1182 /* Give the overlay scaler a chance to disable if it's on this pipe */ 1183 i830_crtc_dpms_video(crtc, FALSE); 1184 1185 /* 1186 * The documentation says : 1187 * - Disable planes (VGA or hires) 1188 * - Disable pipe 1189 * - Disable VGA display 1190 */ 1191 1192 /* Disable display plane */ 1193 temp = INREG(dspcntr_reg); 1194 if ((temp & DISPLAY_PLANE_ENABLE) != 0) 1195 { 1196 OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); 1197 /* Flush the plane changes */ 1198 OUTREG(dspbase_reg, INREG(dspbase_reg)); 1199 POSTING_READ(dspbase_reg); 1200 } 1201 1202 if (!IS_I9XX(pI830)) { 1203 /* Wait for vblank for the disable to take effect */ 1204 i830WaitForVblank(pScrn); 1205 } 1206 1207 /* May need to leave pipe A on */ 1208 if (disable_pipe) 1209 { 1210 /* Next, disable display pipes */ 1211 temp = INREG(pipeconf_reg); 1212 if ((temp & PIPEACONF_ENABLE) != 0) { 1213 OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE); 1214 POSTING_READ(pipeconf_reg); 1215 } 1216 1217 /* Wait for vblank for the disable to take effect. */ 1218 i830WaitForVblank(pScrn); 1219 1220 temp = INREG(dpll_reg); 1221 if ((temp & DPLL_VCO_ENABLE) != 0) { 1222 OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE); 1223 POSTING_READ(dpll_reg); 1224 } 1225 1226 /* Wait for the clocks to turn off. */ 1227 usleep(150); 1228 } 1229 1230 /* Disable the VGA plane that we never use. */ 1231 i830_disable_vga_plane (crtc); 1232} 1233 1234/** 1235 * Sets the power management mode of the pipe and plane. 1236 * 1237 * This code should probably grow support for turning the cursor off and back 1238 * on appropriately at the same time as we're turning the pipe off/on. 1239 */ 1240static void 1241i830_crtc_dpms(xf86CrtcPtr crtc, int mode) 1242{ 1243 ScrnInfoPtr pScrn = crtc->scrn; 1244 I830Ptr pI830 = I830PTR(pScrn); 1245 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1246 int pipe = intel_crtc->pipe; 1247 Bool disable_pipe = TRUE; 1248 1249 /* XXX: When our outputs are all unaware of DPMS modes other than off and 1250 * on, we should map those modes to DPMSModeOff in the CRTC. 1251 */ 1252 switch (mode) { 1253 case DPMSModeOn: 1254 case DPMSModeStandby: 1255 case DPMSModeSuspend: 1256 i830_crtc_enable(crtc); 1257 break; 1258 case DPMSModeOff: 1259 if ((pipe == 0) && (pI830->quirk_flag & QUIRK_PIPEA_FORCE)) 1260 disable_pipe = FALSE; 1261 i830_crtc_disable(crtc, disable_pipe); 1262 intel_crtc->enabled = FALSE; 1263 break; 1264 } 1265 1266 intel_crtc->dpms_mode = mode; 1267} 1268 1269static Bool 1270i830_crtc_lock (xf86CrtcPtr crtc) 1271{ 1272 /* Sync the engine before mode switch, to finish any outstanding 1273 * WAIT_FOR_EVENTS that may rely on CRTC state. 1274 */ 1275 I830Sync(crtc->scrn); 1276 1277 return FALSE; 1278} 1279 1280static void 1281i830_crtc_unlock (xf86CrtcPtr crtc) 1282{ 1283} 1284 1285static void 1286i830_crtc_prepare (xf86CrtcPtr crtc) 1287{ 1288 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1289 /* Temporarily turn off FB compression during modeset */ 1290 if (i830_use_fb_compression(crtc)) 1291 i830_disable_fb_compression(crtc); 1292 if (intel_crtc->enabled) 1293 crtc->funcs->hide_cursor (crtc); 1294 crtc->funcs->dpms (crtc, DPMSModeOff); 1295} 1296 1297static void 1298i830_crtc_commit (xf86CrtcPtr crtc) 1299{ 1300 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1301 Bool deactivate = FALSE; 1302 1303 if (!intel_crtc->enabled && intel_crtc->pipe != 0) 1304 deactivate = i830_pipe_a_require_activate (crtc->scrn); 1305 1306 intel_crtc->enabled = TRUE; 1307 1308 crtc->funcs->dpms (crtc, DPMSModeOn); 1309 if (crtc->scrn->pScreen != NULL) 1310 xf86_reload_cursors (crtc->scrn->pScreen); 1311 if (deactivate) 1312 i830_pipe_a_require_deactivate (crtc->scrn); 1313 1314 /* Reenable FB compression if possible */ 1315 if (i830_use_fb_compression(crtc)) 1316 i830_enable_fb_compression(crtc); 1317} 1318 1319void 1320i830_output_prepare (xf86OutputPtr output) 1321{ 1322 output->funcs->dpms (output, DPMSModeOff); 1323} 1324 1325void 1326i830_output_commit (xf86OutputPtr output) 1327{ 1328 output->funcs->dpms (output, DPMSModeOn); 1329} 1330 1331static Bool 1332i830_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 1333 DisplayModePtr adjusted_mode) 1334{ 1335 return TRUE; 1336} 1337 1338/** Returns the core display clock speed for i830 - i945 */ 1339static int 1340i830_get_core_clock_speed(ScrnInfoPtr pScrn) 1341{ 1342 I830Ptr pI830 = I830PTR(pScrn); 1343 1344 /* Core clock values taken from the published datasheets. 1345 * The 830 may go up to 166 Mhz, which we should check. 1346 */ 1347 if (IS_I945G(pI830) || (IS_G33CLASS(pI830) && !IS_IGDGM(pI830))) 1348 return 400000; 1349 else if (IS_I915G(pI830)) 1350 return 333000; 1351 else if (IS_I945GM(pI830) || IS_845G(pI830) || IS_IGDGM(pI830)) 1352 return 200000; 1353 else if (IS_I915GM(pI830)) { 1354 uint16_t gcfgc; 1355 1356 pci_device_cfg_read_u16 (pI830->PciInfo, &gcfgc, I915_GCFGC); 1357 if (gcfgc & I915_LOW_FREQUENCY_ENABLE) 1358 return 133000; 1359 else { 1360 switch (gcfgc & I915_DISPLAY_CLOCK_MASK) { 1361 case I915_DISPLAY_CLOCK_333_MHZ: 1362 return 333000; 1363 default: 1364 case I915_DISPLAY_CLOCK_190_200_MHZ: 1365 return 190000; 1366 } 1367 } 1368 } else if (IS_I865G(pI830)) 1369 return 266000; 1370 else if (IS_I855(pI830)) { 1371 struct pci_device *bridge = intel_host_bridge (); 1372 uint16_t hpllcc; 1373 pci_device_cfg_read_u16 (bridge, &hpllcc, I855_HPLLCC); 1374 1375 /* Assume that the hardware is in the high speed state. This 1376 * should be the default. 1377 */ 1378 switch (hpllcc & I855_CLOCK_CONTROL_MASK) { 1379 case I855_CLOCK_133_200: 1380 case I855_CLOCK_100_200: 1381 return 200000; 1382 case I855_CLOCK_166_250: 1383 return 250000; 1384 case I855_CLOCK_100_133: 1385 return 133000; 1386 } 1387 } else /* 852, 830 */ 1388 return 133000; 1389 1390 return 0; /* Silence gcc warning */ 1391} 1392 1393/** 1394 * Return the pipe currently connected to the panel fitter, 1395 * or -1 if the panel fitter is not present or not in use 1396 */ 1397static int 1398i830_panel_fitter_pipe(I830Ptr pI830) 1399{ 1400 uint32_t pfit_control; 1401 1402 /* i830 doesn't have a panel fitter */ 1403 if (IS_I830(pI830)) 1404 return -1; 1405 1406 pfit_control = INREG(PFIT_CONTROL); 1407 1408 /* See if the panel fitter is in use */ 1409 if ((pfit_control & PFIT_ENABLE) == 0) 1410 return -1; 1411 1412 /* 965 can place panel fitter on either pipe */ 1413 if (IS_I965G(pI830)) 1414 return (pfit_control & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT; 1415 1416 /* older chips can only use pipe 1 */ 1417 return 1; 1418} 1419 1420/** 1421 * Sets up the DSPARB register to split the display fifo appropriately between 1422 * the display planes. 1423 * 1424 * Adjusting this register requires that the planes be off. 1425 */ 1426static void 1427i830_update_dsparb(ScrnInfoPtr pScrn) 1428{ 1429 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1430 I830Ptr pI830 = I830PTR(pScrn); 1431 int total_hdisplay = 0, planea_hdisplay = 0, planeb_hdisplay = 0; 1432 int fifo_entries = 0, planea_entries = 0, planeb_entries = 0, i; 1433 1434 if ((INREG(DSPACNTR) & DISPLAY_PLANE_ENABLE) && 1435 (INREG(DSPBCNTR) & DISPLAY_PLANE_ENABLE)) 1436 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1437 "tried to update DSPARB with both planes enabled!\n"); 1438 1439 /* 1440 * FIFO entries will be split based on programmed modes 1441 */ 1442 if (IS_I965GM(pI830)) 1443 fifo_entries = 127; 1444 else if (IS_I9XX(pI830)) 1445 fifo_entries = 95; 1446 else if (IS_MOBILE(pI830)) { 1447 fifo_entries = 255; 1448 } else { 1449 /* The 845/865 only have a AEND field. Though the field size would 1450 * allow 128 entries, the 865 rendered the cursor wrong then. 1451 * The BIOS set it up for 96. 1452 */ 1453 fifo_entries = 95; 1454 } 1455 1456 for (i = 0; i < xf86_config->num_crtc; i++) { 1457 xf86CrtcPtr crtc = xf86_config->crtc[i]; 1458 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1459 if (crtc->enabled) { 1460 total_hdisplay += crtc->mode.HDisplay; 1461 if (intel_crtc->plane == 0) 1462 planea_hdisplay = crtc->mode.HDisplay; 1463 else 1464 planeb_hdisplay = crtc->mode.HDisplay; 1465 } 1466 } 1467 1468 planea_entries = fifo_entries * planea_hdisplay / total_hdisplay; 1469 planeb_entries = fifo_entries * planeb_hdisplay / total_hdisplay; 1470 1471 if (IS_I9XX(pI830)) 1472 OUTREG(DSPARB, 1473 ((planea_entries + planeb_entries) << DSPARB_CSTART_SHIFT) | 1474 (planea_entries << DSPARB_BSTART_SHIFT)); 1475 else if (IS_MOBILE(pI830)) 1476 OUTREG(DSPARB, 1477 ((planea_entries + planeb_entries) << DSPARB_BEND_SHIFT) | 1478 (planea_entries << DSPARB_AEND_SHIFT)); 1479 else 1480 OUTREG(DSPARB, planea_entries << DSPARB_AEND_SHIFT); 1481} 1482 1483/** 1484 * Sets up registers for the given mode/adjusted_mode pair. 1485 * 1486 * The clocks, CRTCs and outputs attached to this CRTC must be off. 1487 * 1488 * This shouldn't enable any clocks, CRTCs, or outputs, but they should 1489 * be easily turned on/off after this. 1490 */ 1491static void 1492i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 1493 DisplayModePtr adjusted_mode, 1494 int x, int y) 1495{ 1496 ScrnInfoPtr pScrn = crtc->scrn; 1497 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1498 I830Ptr pI830 = I830PTR(pScrn); 1499 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1500 I830OutputPrivatePtr intel_output; 1501 int pipe = intel_crtc->pipe; 1502 int plane = intel_crtc->plane; 1503 int fp_reg = (pipe == 0) ? FPA0 : FPB0; 1504 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; 1505 int dpll_md_reg = (pipe == 0) ? DPLL_A_MD : DPLL_B_MD; 1506 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; 1507 int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; 1508 int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; 1509 int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; 1510 int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; 1511 int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; 1512 int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; 1513 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; 1514 int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; 1515 int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; 1516 int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; 1517 int i, num_outputs = 0; 1518 int refclk; 1519 intel_clock_t clock; 1520 uint32_t dpll = 0, fp = 0, dspcntr, pipeconf, lvds_bits = 0; 1521 Bool ok, is_sdvo = FALSE, is_dvo = FALSE; 1522 Bool is_crt = FALSE, is_lvds = FALSE, is_tv = FALSE; 1523 const intel_limit_t *limit; 1524 1525 /* Set up some convenient bools for what outputs are connected to 1526 * our pipe, used in DPLL setup. 1527 */ 1528 for (i = 0; i < xf86_config->num_output; i++) { 1529 xf86OutputPtr output = xf86_config->output[i]; 1530 intel_output = output->driver_private; 1531 1532 if (output->crtc != crtc) 1533 continue; 1534 1535 switch (intel_output->type) { 1536 case I830_OUTPUT_LVDS: 1537 is_lvds = TRUE; 1538 lvds_bits = intel_output->lvds_bits; 1539 break; 1540 case I830_OUTPUT_SDVO: 1541 case I830_OUTPUT_HDMI: 1542 is_sdvo = TRUE; 1543 if (intel_output->needs_tv_clock) 1544 is_tv = TRUE; 1545 break; 1546 case I830_OUTPUT_DVO_TMDS: 1547 case I830_OUTPUT_DVO_LVDS: 1548 case I830_OUTPUT_DVO_TVOUT: 1549 is_dvo = TRUE; 1550 break; 1551 case I830_OUTPUT_TVOUT: 1552 is_tv = TRUE; 1553 break; 1554 case I830_OUTPUT_ANALOG: 1555 is_crt = TRUE; 1556 break; 1557 } 1558 1559 num_outputs++; 1560 } 1561 1562 if (num_outputs > 1) 1563 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "clone detected, disabling SSC\n"); 1564 1565 /* Don't use SSC when cloned */ 1566 if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2) { 1567 refclk = pI830->lvds_ssc_freq * 1000; 1568 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1569 "using SSC reference clock of %d MHz\n", refclk / 1000); 1570 } else if (IS_I9XX(pI830)) { 1571 refclk = 96000; 1572 } else { 1573 refclk = 48000; 1574 } 1575 1576 /* 1577 * Returns a set of divisors for the desired target clock with the given 1578 * refclk, or FALSE. The returned values represent the clock equation: 1579 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. 1580 */ 1581 limit = intel_limit (crtc); 1582 ok = limit->find_pll(limit, crtc, adjusted_mode->Clock, refclk, &clock); 1583 if (!ok) 1584 FatalError("Couldn't find PLL settings for mode!\n"); 1585 1586 if (fabs(adjusted_mode->Clock - clock.dot) / clock.dot > .02) { 1587 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1588 "Chosen PLL clock of %.1f Mhz more than 2%% away from " 1589 "desired %.1f Mhz\n", 1590 (float)clock.dot / 1000, 1591 (float)adjusted_mode->Clock / 1000); 1592 } 1593 1594 /* SDVO TV has fixed PLL values depends on its clock range, 1595 this mirrors vbios setting. */ 1596 if (is_sdvo && is_tv) { 1597 if (adjusted_mode->Clock >= 100000 && 1598 adjusted_mode->Clock < 140500) { 1599 clock.p1 = 2; 1600 clock.p2 = 10; 1601 clock.n = 3; 1602 clock.m1 = 16; 1603 clock.m2 = 8; 1604 } else if (adjusted_mode->Clock >= 140500 && 1605 adjusted_mode->Clock <= 200000) { 1606 clock.p1 = 1; 1607 clock.p2 = 10; 1608 clock.n = 6; 1609 clock.m1 = 12; 1610 clock.m2 = 8; 1611 } 1612 } 1613 1614 if (IS_IGD(pI830)) 1615 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; 1616 else 1617 fp = clock.n << 16 | clock.m1 << 8 | clock.m2; 1618 1619 dpll = DPLL_VGA_MODE_DIS; 1620 if (IS_I9XX(pI830)) { 1621 if (is_lvds) 1622 dpll |= DPLLB_MODE_LVDS; 1623 else 1624 dpll |= DPLLB_MODE_DAC_SERIAL; 1625 if (is_sdvo) 1626 { 1627 dpll |= DPLL_DVO_HIGH_SPEED; 1628 if ((IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))) 1629 { 1630 int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock; 1631 dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; 1632 } 1633 } 1634 1635 /* compute bitmask from p1 value */ 1636 if (IS_IGD(pI830)) 1637 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD; 1638 else 1639 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; 1640 switch (clock.p2) { 1641 case 5: 1642 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; 1643 break; 1644 case 7: 1645 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7; 1646 break; 1647 case 10: 1648 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10; 1649 break; 1650 case 14: 1651 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; 1652 break; 1653 } 1654 if (IS_I965G(pI830) && !IS_GM45(pI830)) 1655 dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); 1656 } else { 1657 if (is_lvds) { 1658 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; 1659 } else { 1660 if (clock.p1 == 2) 1661 dpll |= PLL_P1_DIVIDE_BY_TWO; 1662 else 1663 dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT; 1664 if (clock.p2 == 4) 1665 dpll |= PLL_P2_DIVIDE_BY_4; 1666 } 1667 } 1668 1669 if (is_sdvo && is_tv) 1670 dpll |= PLL_REF_INPUT_TVCLKINBC; 1671 else if (is_tv) 1672 { 1673 /* XXX: just matching BIOS for now */ 1674/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ 1675 dpll |= 3; 1676 } 1677 else if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2) 1678 dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; 1679 else 1680 dpll |= PLL_REF_INPUT_DREFCLK; 1681 1682 /* Set up the display plane register */ 1683 dspcntr = DISPPLANE_GAMMA_ENABLE; 1684 switch (pScrn->bitsPerPixel) { 1685 case 8: 1686 dspcntr |= DISPPLANE_8BPP; 1687 break; 1688 case 16: 1689 if (pScrn->depth == 15) 1690 dspcntr |= DISPPLANE_15_16BPP; 1691 else 1692 dspcntr |= DISPPLANE_16BPP; 1693 break; 1694 case 32: 1695 dspcntr |= DISPPLANE_32BPP_NO_ALPHA; 1696 break; 1697 default: 1698 FatalError("unknown display bpp\n"); 1699 } 1700 1701 if (pipe == 0) 1702 dspcntr |= DISPPLANE_SEL_PIPE_A; 1703 else 1704 dspcntr |= DISPPLANE_SEL_PIPE_B; 1705 1706 if (IS_I965G(pI830) && i830_display_tiled(crtc)) 1707 dspcntr |= DISPLAY_PLANE_TILED; 1708 1709 pipeconf = INREG(pipeconf_reg); 1710 if (pipe == 0 && !IS_I965G(pI830)) 1711 { 1712 /* Enable pixel doubling when the dot clock is > 90% of the (display) 1713 * core speed. 1714 * 1715 * XXX: No double-wide on 915GM pipe B. Is that the only reason for the 1716 * pipe == 0 check? 1717 */ 1718 if (mode->Clock > i830_get_core_clock_speed(pScrn) * 9 / 10) 1719 pipeconf |= PIPEACONF_DOUBLE_WIDE; 1720 else 1721 pipeconf &= ~PIPEACONF_DOUBLE_WIDE; 1722 } 1723 /* 1724 * This "shouldn't" be needed as the dpms on code 1725 * will be run after the mode is set. On 9xx, it helps. 1726 * On 855, it can lock up the chip (and the entire machine) 1727 */ 1728 if (!IS_I85X (pI830)) 1729 { 1730 dspcntr |= DISPLAY_PLANE_ENABLE; 1731 pipeconf |= PIPEACONF_ENABLE; 1732 dpll |= DPLL_VCO_ENABLE; 1733 } 1734 1735 /* Disable the panel fitter if it was on our pipe */ 1736 if (i830_panel_fitter_pipe (pI830) == pipe) 1737 OUTREG(PFIT_CONTROL, 0); 1738 1739 if (pI830->debug_modes) { 1740 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1741 "Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); 1742 xf86PrintModeline(pScrn->scrnIndex, mode); 1743 if (!xf86ModesEqual(mode, adjusted_mode)) { 1744 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1745 "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); 1746 xf86PrintModeline(pScrn->scrnIndex, adjusted_mode); 1747 } 1748 i830PrintPll(pScrn, "chosen", &clock); 1749 } 1750 1751 if (dpll & DPLL_VCO_ENABLE) 1752 { 1753 OUTREG(fp_reg, fp); 1754 OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE); 1755 POSTING_READ(dpll_reg); 1756 usleep(150); 1757 } 1758 1759 /* The LVDS pin pair needs to be on before the DPLLs are enabled. 1760 * This is an exception to the general rule that mode_set doesn't turn 1761 * things on. 1762 */ 1763 if (is_lvds) 1764 { 1765 uint32_t lvds = INREG(LVDS); 1766 1767 lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; 1768 /* Set the B0-B3 data pairs corresponding to whether we're going to 1769 * set the DPLLs for dual-channel mode or not. 1770 */ 1771 if (clock.p2 == I9XX_P2_LVDS_FAST) 1772 lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; 1773 else 1774 lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); 1775 1776 if (pI830->lvds_24_bit_mode) { 1777 /* Option set which requests 24-bit mode 1778 * (LVDS_A3_POWER_UP, as opposed to 18-bit mode) here; we 1779 * still need to look more thoroughly into how panels 1780 * behave in the two modes. This option enables that 1781 * experimentation. 1782 */ 1783 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1784 "Selecting less common 24 bit TMDS pixel format.\n"); 1785 lvds |= LVDS_A3_POWER_UP; 1786 lvds |= LVDS_DATA_FORMAT_DOT_ONE; 1787 } else { 1788 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1789 "Selecting standard 18 bit TMDS pixel format.\n"); 1790 } 1791 1792 /* Enable dithering if we're in 18-bit mode. */ 1793 if (IS_I965G(pI830)) 1794 { 1795 if ((lvds & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) 1796 lvds &= ~LVDS_DITHER_ENABLE; 1797 else 1798 lvds |= LVDS_DITHER_ENABLE; 1799 } 1800 1801 lvds |= lvds_bits; 1802 1803 OUTREG(LVDS, lvds); 1804 POSTING_READ(LVDS); 1805 } 1806 1807 OUTREG(fp_reg, fp); 1808 OUTREG(dpll_reg, dpll); 1809 POSTING_READ(dpll_reg); 1810 /* Wait for the clocks to stabilize. */ 1811 usleep(150); 1812 1813 if (IS_I965G(pI830)) { 1814 int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock; 1815 OUTREG(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | 1816 ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); 1817 } else { 1818 /* write it again -- the BIOS does, after all */ 1819 OUTREG(dpll_reg, dpll); 1820 } 1821 POSTING_READ(dpll_reg); 1822 /* Wait for the clocks to stabilize. */ 1823 usleep(150); 1824 1825 if (!DSPARB_HWCONTROL(pI830)) 1826 i830_update_dsparb(pScrn); 1827 1828 OUTREG(htot_reg, (adjusted_mode->CrtcHDisplay - 1) | 1829 ((adjusted_mode->CrtcHTotal - 1) << 16)); 1830 OUTREG(hblank_reg, (adjusted_mode->CrtcHBlankStart - 1) | 1831 ((adjusted_mode->CrtcHBlankEnd - 1) << 16)); 1832 OUTREG(hsync_reg, (adjusted_mode->CrtcHSyncStart - 1) | 1833 ((adjusted_mode->CrtcHSyncEnd - 1) << 16)); 1834 OUTREG(vtot_reg, (adjusted_mode->CrtcVDisplay - 1) | 1835 ((adjusted_mode->CrtcVTotal - 1) << 16)); 1836 1837 OUTREG(vblank_reg, (adjusted_mode->CrtcVBlankStart - 1) | 1838 ((adjusted_mode->CrtcVBlankEnd - 1) << 16)); 1839 OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) | 1840 ((adjusted_mode->CrtcVSyncEnd - 1) << 16)); 1841 /* pipesrc and dspsize control the size that is scaled from, which should 1842 * always be the user's requested size. 1843 */ 1844 OUTREG(dspsize_reg, ((mode->VDisplay - 1) << 16) | (mode->HDisplay - 1)); 1845 OUTREG(dsppos_reg, 0); 1846 OUTREG(pipesrc_reg, ((mode->HDisplay - 1) << 16) | (mode->VDisplay - 1)); 1847 OUTREG(pipeconf_reg, pipeconf); 1848 POSTING_READ(pipeconf_reg); 1849 i830WaitForVblank(pScrn); 1850 1851 OUTREG(dspcntr_reg, dspcntr); 1852 /* Flush the plane changes */ 1853 i830PipeSetBase(crtc, x, y); 1854 1855 i830WaitForVblank(pScrn); 1856} 1857 1858 1859/** Loads the palette/gamma unit for the CRTC with the prepared values */ 1860static void 1861i830_crtc_load_lut(xf86CrtcPtr crtc) 1862{ 1863 ScrnInfoPtr pScrn = crtc->scrn; 1864 I830Ptr pI830 = I830PTR(pScrn); 1865 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1866 int palreg = (intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B; 1867 int i; 1868 1869 /* The clocks have to be on to load the palette. */ 1870 if (!crtc->enabled) 1871 return; 1872 1873 for (i = 0; i < 256; i++) { 1874 OUTREG(palreg + 4 * i, 1875 (intel_crtc->lut_r[i] << 16) | 1876 (intel_crtc->lut_g[i] << 8) | 1877 intel_crtc->lut_b[i]); 1878 } 1879} 1880 1881/** Sets the color ramps on behalf of RandR */ 1882static void 1883i830_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, 1884 int size) 1885{ 1886 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1887 int i; 1888 1889 assert(size == 256); 1890 1891 for (i = 0; i < 256; i++) { 1892 intel_crtc->lut_r[i] = red[i] >> 8; 1893 intel_crtc->lut_g[i] = green[i] >> 8; 1894 intel_crtc->lut_b[i] = blue[i] >> 8; 1895 } 1896 1897 i830_crtc_load_lut(crtc); 1898} 1899 1900/** 1901 * Allocates memory for a locked-in-framebuffer shadow of the given 1902 * width and height for this CRTC's rotated shadow framebuffer. 1903 */ 1904 1905static void * 1906i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) 1907{ 1908 ScrnInfoPtr pScrn = crtc->scrn; 1909 I830Ptr pI830 = I830PTR(pScrn); 1910 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1911 unsigned long rotate_pitch; 1912 int align = KB(4), size; 1913 1914 width = i830_pad_drawable_width(width, pI830->cpp); 1915 rotate_pitch = width * pI830->cpp; 1916 size = rotate_pitch * height; 1917 1918 assert(intel_crtc->rotate_mem == NULL); 1919 intel_crtc->rotate_mem = i830_allocate_memory(pScrn, "rotated crtc", 1920 size, rotate_pitch, align, 1921 0, TILE_NONE); 1922 if (intel_crtc->rotate_mem == NULL) { 1923 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1924 "Couldn't allocate shadow memory for rotated CRTC\n"); 1925 return NULL; 1926 } 1927 memset(pI830->FbBase + intel_crtc->rotate_mem->offset, 0, size); 1928 1929 return pI830->FbBase + intel_crtc->rotate_mem->offset; 1930} 1931 1932/** 1933 * Creates a pixmap for this CRTC's rotated shadow framebuffer. 1934 */ 1935static PixmapPtr 1936i830_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 1937{ 1938 ScrnInfoPtr pScrn = crtc->scrn; 1939 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1940 I830Ptr pI830 = I830PTR(pScrn); 1941 int rotate_pitch; 1942 PixmapPtr rotate_pixmap; 1943 1944 if (!data) 1945 data = i830_crtc_shadow_allocate (crtc, width, height); 1946 1947 rotate_pitch = i830_pad_drawable_width(width, pI830->cpp) * pI830->cpp; 1948 1949 rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, 1950 width, height, 1951 pScrn->depth, 1952 pScrn->bitsPerPixel, 1953 rotate_pitch, 1954 data); 1955 1956 if (rotate_pixmap == NULL) { 1957 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1958 "Couldn't allocate shadow pixmap for rotated CRTC\n"); 1959 } 1960 if (intel_crtc->rotate_mem && intel_crtc->rotate_mem->bo) 1961 i830_set_pixmap_bo(rotate_pixmap, intel_crtc->rotate_mem->bo); 1962 return rotate_pixmap; 1963} 1964 1965static void 1966i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 1967{ 1968 ScrnInfoPtr pScrn = crtc->scrn; 1969 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 1970 1971 if (rotate_pixmap) { 1972 i830_set_pixmap_bo(rotate_pixmap, NULL); 1973 FreeScratchPixmapHeader(rotate_pixmap); 1974 } 1975 1976 if (data) { 1977 /* Be sure to sync acceleration before the memory gets unbound. */ 1978 I830Sync(pScrn); 1979 i830_free_memory(pScrn, intel_crtc->rotate_mem); 1980 intel_crtc->rotate_mem = NULL; 1981 } 1982} 1983 1984#if RANDR_13_INTERFACE 1985static void 1986i830_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) 1987{ 1988 if (crtc->enabled) 1989 i830PipeSetBase(crtc, x, y); 1990} 1991#endif 1992 1993/* The screen bo has changed, reset each active crtc to point at 1994 * the same location that it currently points at, but in the new bo 1995 */ 1996void 1997i830_set_new_crtc_bo(ScrnInfoPtr pScrn) 1998{ 1999 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2000 int i; 2001 2002 for (i = 0; i < xf86_config->num_crtc; i++) { 2003 xf86CrtcPtr crtc = xf86_config->crtc[i]; 2004 2005 if (crtc->enabled && !crtc->transform_in_use) 2006 i830PipeSetBase(crtc, crtc->x, crtc->y); 2007 } 2008} 2009 2010void 2011i830DescribeOutputConfiguration(ScrnInfoPtr pScrn) 2012{ 2013 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2014 I830Ptr pI830 = I830PTR(pScrn); 2015 int i; 2016 2017 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output configuration:\n"); 2018 2019 for (i = 0; i < xf86_config->num_crtc; i++) { 2020 xf86CrtcPtr crtc = xf86_config->crtc[i]; 2021 I830CrtcPrivatePtr intel_crtc = crtc ? crtc->driver_private : NULL; 2022 uint32_t dspcntr = intel_crtc->plane == 0 ? INREG(DSPACNTR) : 2023 INREG(DSPBCNTR); 2024 uint32_t pipeconf = i == 0 ? INREG(PIPEACONF) : 2025 INREG(PIPEBCONF); 2026 Bool hw_plane_enable = (dspcntr & DISPLAY_PLANE_ENABLE) != 0; 2027 Bool hw_pipe_enable = (pipeconf & PIPEACONF_ENABLE) != 0; 2028 2029 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2030 " Pipe %c is %s\n", 2031 'A' + i, crtc->enabled ? "on" : "off"); 2032 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2033 " Display plane %c is now %s and connected to pipe %c.\n", 2034 'A' + intel_crtc->plane, 2035 hw_plane_enable ? "enabled" : "disabled", 2036 dspcntr & DISPPLANE_SEL_PIPE_MASK ? 'B' : 'A'); 2037 if (hw_pipe_enable != crtc->enabled) { 2038 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2039 " Hardware claims pipe %c is %s while software " 2040 "believes it is %s\n", 2041 'A' + i, hw_pipe_enable ? "on" : "off", 2042 crtc->enabled ? "on" : "off"); 2043 } 2044 if (hw_plane_enable != crtc->enabled) { 2045 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2046 " Hardware claims plane %c is %s while software " 2047 "believes it is %s\n", 2048 'A' + i, hw_plane_enable ? "on" : "off", 2049 crtc->enabled ? "on" : "off"); 2050 } 2051 } 2052 2053 for (i = 0; i < xf86_config->num_output; i++) { 2054 xf86OutputPtr output = xf86_config->output[i]; 2055 xf86CrtcPtr crtc = output->crtc; 2056 I830CrtcPrivatePtr intel_crtc = crtc ? crtc->driver_private : NULL; 2057 2058 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2059 " Output %s is connected to pipe %s\n", 2060 output->name, intel_crtc == NULL ? "none" : 2061 (intel_crtc->pipe == 0 ? "A" : "B")); 2062 } 2063} 2064 2065/** 2066 * Get a pipe with a simple mode set on it for doing load-based monitor 2067 * detection. 2068 * 2069 * It will be up to the load-detect code to adjust the pipe as appropriate for 2070 * its requirements. The pipe will be connected to no other outputs. 2071 * 2072 * Currently this code will only succeed if there is a pipe with no outputs 2073 * configured for it. In the future, it could choose to temporarily disable 2074 * some outputs to free up a pipe for its use. 2075 * 2076 * \return crtc, or NULL if no pipes are available. 2077 */ 2078 2079/* VESA 640x480x72Hz mode to set on the pipe */ 2080static DisplayModeRec load_detect_mode = { 2081 NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT, 2082 31500, 2083 640, 664, 704, 832, 0, 2084 480, 489, 491, 520, 0, 2085 V_NHSYNC | V_NVSYNC, 2086 0, 0, 2087 2088 640, 640, 664, 704, 832, 832, 0, 2089 480, 489, 489, 491, 520, 520, 2090 FALSE, FALSE, 0, NULL, 0, 0.0, 0.0 2091}; 2092 2093xf86CrtcPtr 2094i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode) 2095{ 2096 ScrnInfoPtr pScrn = output->scrn; 2097 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2098 I830OutputPrivatePtr intel_output = output->driver_private; 2099 I830CrtcPrivatePtr intel_crtc; 2100 xf86CrtcPtr supported_crtc =NULL; 2101 xf86CrtcPtr crtc = NULL; 2102 int i; 2103 2104 if (output->crtc) 2105 { 2106 crtc = output->crtc; 2107 /* 2108 * Make sure the crtc and output are running 2109 */ 2110 intel_crtc = crtc->driver_private; 2111 *dpms_mode = intel_crtc->dpms_mode; 2112 if (intel_crtc->dpms_mode != DPMSModeOn) 2113 { 2114 crtc->funcs->dpms (crtc, DPMSModeOn); 2115 output->funcs->dpms (output, DPMSModeOn); 2116 } 2117 return crtc; 2118 } 2119 2120 for (i = 0; i < xf86_config->num_crtc; i++) 2121 { 2122 xf86CrtcPtr possible_crtc; 2123 if (!(output->possible_crtcs & (1 << i))) 2124 continue; 2125 possible_crtc = xf86_config->crtc[i]; 2126 if (!possible_crtc->enabled) 2127 { 2128 crtc = possible_crtc; 2129 break; 2130 } 2131 if (!supported_crtc) 2132 supported_crtc = possible_crtc; 2133 } 2134 if (!crtc) 2135 { 2136 crtc = supported_crtc; 2137 if (!crtc) 2138 return NULL; 2139 } 2140 2141 output->crtc = crtc; 2142 intel_output->load_detect_temp = TRUE; 2143 2144 intel_crtc = crtc->driver_private; 2145 *dpms_mode = intel_crtc->dpms_mode; 2146 2147 if (!crtc->enabled) 2148 { 2149 if (!mode) 2150 mode = &load_detect_mode; 2151 xf86CrtcSetMode (crtc, mode, RR_Rotate_0, 0, 0); 2152 } 2153 else 2154 { 2155 if (intel_crtc->dpms_mode != DPMSModeOn) 2156 crtc->funcs->dpms (crtc, DPMSModeOn); 2157 2158 /* Add this output to the crtc */ 2159 output->funcs->mode_set (output, &crtc->mode, &crtc->mode); 2160 output->funcs->commit (output); 2161 } 2162 /* let the output get through one full cycle before testing */ 2163 i830WaitForVblank (pScrn); 2164 2165 return crtc; 2166} 2167 2168void 2169i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode) 2170{ 2171 ScrnInfoPtr pScrn = output->scrn; 2172 I830OutputPrivatePtr intel_output = output->driver_private; 2173 xf86CrtcPtr crtc = output->crtc; 2174 2175 if (intel_output->load_detect_temp) 2176 { 2177 output->crtc = NULL; 2178 intel_output->load_detect_temp = FALSE; 2179 crtc->enabled = xf86CrtcInUse (crtc); 2180 xf86DisableUnusedFunctions(pScrn); 2181 } 2182 /* 2183 * Switch crtc and output back off if necessary 2184 */ 2185 if (crtc->enabled && dpms_mode != DPMSModeOn) 2186 { 2187 if (output->crtc == crtc) 2188 output->funcs->dpms (output, dpms_mode); 2189 crtc->funcs->dpms (crtc, dpms_mode); 2190 } 2191} 2192 2193/* Returns the clock of the currently programmed mode of the given pipe. */ 2194static int 2195i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) 2196{ 2197 I830Ptr pI830 = I830PTR(pScrn); 2198 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 2199 int pipe = intel_crtc->pipe; 2200 uint32_t dpll = INREG((pipe == 0) ? DPLL_A : DPLL_B); 2201 uint32_t fp; 2202 intel_clock_t clock; 2203 2204 if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) 2205 fp = INREG((pipe == 0) ? FPA0 : FPB0); 2206 else 2207 fp = INREG((pipe == 0) ? FPA1 : FPB1); 2208 2209 clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; 2210 if (IS_IGD(pI830)) { 2211 clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; 2212 clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT; 2213 } else { 2214 clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; 2215 clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; 2216 } 2217 if (IS_I9XX(pI830)) { 2218 if (IS_IGD(pI830)) 2219 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >> 2220 DPLL_FPA01_P1_POST_DIV_SHIFT_IGD); 2221 else 2222 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> 2223 DPLL_FPA01_P1_POST_DIV_SHIFT); 2224 2225 switch (dpll & DPLL_MODE_MASK) { 2226 case DPLLB_MODE_DAC_SERIAL: 2227 clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; 2228 break; 2229 case DPLLB_MODE_LVDS: 2230 clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; 2231 break; 2232 default: 2233 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2234 "Unknown DPLL mode %08x in programmed mode\n", 2235 (int)(dpll & DPLL_MODE_MASK)); 2236 return 0; 2237 } 2238 2239 if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) 2240 intel_clock(pI830, 100000, &clock); 2241 else 2242 intel_clock(pI830, 96000, &clock); 2243 } else { 2244 Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN); 2245 2246 if (is_lvds) { 2247 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> 2248 DPLL_FPA01_P1_POST_DIV_SHIFT); 2249 2250 /* if LVDS is dual-channel, p2 = 7 */ 2251 if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) 2252 clock.p2 = 7; 2253 else 2254 clock.p2 = 14; 2255 2256 if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) 2257 intel_clock(pI830, 66000, &clock); /* XXX: might not be 66MHz */ 2258 else 2259 intel_clock(pI830, 48000, &clock); 2260 } else { 2261 if (dpll & PLL_P1_DIVIDE_BY_TWO) { 2262 clock.p1 = 2; 2263 } else { 2264 clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> 2265 DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; 2266 } 2267 if (dpll & PLL_P2_DIVIDE_BY_4) 2268 clock.p2 = 4; 2269 else 2270 clock.p2 = 2; 2271 2272 intel_clock(pI830, 48000, &clock); 2273 } 2274 } 2275 2276 /* XXX: It would be nice to validate the clocks, but we can't reuse 2277 * i830PllIsValid() because it relies on the xf86_config output 2278 * configuration being accurate, which it isn't necessarily. 2279 */ 2280 if (0) 2281 i830PrintPll(pScrn, "probed", &clock); 2282 2283 return clock.dot; 2284} 2285 2286/** Returns the currently programmed mode of the given pipe. */ 2287DisplayModePtr 2288i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) 2289{ 2290 I830Ptr pI830 = I830PTR(pScrn); 2291 I830CrtcPrivatePtr intel_crtc = crtc->driver_private; 2292 int pipe = intel_crtc->pipe; 2293 DisplayModePtr mode; 2294 int htot = INREG((pipe == 0) ? HTOTAL_A : HTOTAL_B); 2295 int hsync = INREG((pipe == 0) ? HSYNC_A : HSYNC_B); 2296 int vtot = INREG((pipe == 0) ? VTOTAL_A : VTOTAL_B); 2297 int vsync = INREG((pipe == 0) ? VSYNC_A : VSYNC_B); 2298 2299 mode = xcalloc(1, sizeof(DisplayModeRec)); 2300 if (mode == NULL) 2301 return NULL; 2302 2303 mode->Clock = i830_crtc_clock_get(pScrn, crtc); 2304 mode->HDisplay = (htot & 0xffff) + 1; 2305 mode->HTotal = ((htot & 0xffff0000) >> 16) + 1; 2306 mode->HSyncStart = (hsync & 0xffff) + 1; 2307 mode->HSyncEnd = ((hsync & 0xffff0000) >> 16) + 1; 2308 mode->VDisplay = (vtot & 0xffff) + 1; 2309 mode->VTotal = ((vtot & 0xffff0000) >> 16) + 1; 2310 mode->VSyncStart = (vsync & 0xffff) + 1; 2311 mode->VSyncEnd = ((vsync & 0xffff0000) >> 16) + 1; 2312 xf86SetModeDefaultName(mode); 2313 xf86SetModeCrtc(mode, 0); 2314 2315 return mode; 2316} 2317 2318static const xf86CrtcFuncsRec i830_crtc_funcs = { 2319 .dpms = i830_crtc_dpms, 2320 .save = NULL, /* XXX */ 2321 .restore = NULL, /* XXX */ 2322 .lock = i830_crtc_lock, 2323 .unlock = i830_crtc_unlock, 2324 .mode_fixup = i830_crtc_mode_fixup, 2325 .prepare = i830_crtc_prepare, 2326 .mode_set = i830_crtc_mode_set, 2327 .commit = i830_crtc_commit, 2328 .gamma_set = i830_crtc_gamma_set, 2329 .shadow_create = i830_crtc_shadow_create, 2330 .shadow_allocate = i830_crtc_shadow_allocate, 2331 .shadow_destroy = i830_crtc_shadow_destroy, 2332 .set_cursor_colors = i830_crtc_set_cursor_colors, 2333 .set_cursor_position = i830_crtc_set_cursor_position, 2334 .show_cursor = i830_crtc_show_cursor, 2335 .hide_cursor = i830_crtc_hide_cursor, 2336 .load_cursor_argb = i830_crtc_load_cursor_argb, 2337 .destroy = NULL, /* XXX */ 2338#if RANDR_13_INTERFACE 2339 .set_origin = i830_crtc_set_origin, 2340#endif 2341}; 2342 2343void 2344i830_crtc_init(ScrnInfoPtr pScrn, int pipe) 2345{ 2346 xf86CrtcPtr crtc; 2347 I830CrtcPrivatePtr intel_crtc; 2348 int i; 2349 2350 crtc = xf86CrtcCreate (pScrn, &i830_crtc_funcs); 2351 if (crtc == NULL) 2352 return; 2353 2354 intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1); 2355 intel_crtc->pipe = pipe; 2356 intel_crtc->dpms_mode = DPMSModeOff; 2357 intel_crtc->plane = pipe; 2358 2359 /* Initialize the LUTs for when we turn on the CRTC. */ 2360 for (i = 0; i < 256; i++) { 2361 intel_crtc->lut_r[i] = i; 2362 intel_crtc->lut_g[i] = i; 2363 intel_crtc->lut_b[i] = i; 2364 } 2365 crtc->driver_private = intel_crtc; 2366} 2367 2368