aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-11-10 16:25:33 -0500
committerDave Airlie <airlied@redhat.com>2013-11-10 16:25:33 -0500
commitcf0613d242805797f252535fcf7bb019512beb46 (patch)
tree5b50ea717d86049a1b2bc99ecb82c9fe140a4714
parent8d01e1ef6766babffb5965218beb207dde693fb5 (diff)
parentcd3fdbe853c47c5890d5362363b59504c2e5fb5f (diff)
Merge branch 'gma500-next' of git://github.com/patjak/drm-gma500 into drm-next
SDVO support for minnowboard * 'gma500-next' of git://github.com/patjak/drm-gma500: drm/gma500/mrst: Add SDVO to output init drm/gma500/mrst: Don't blindly guess a mode for LVDS drm/gma500/mrst: Setup GMBUS for oaktrail/mrst drm/gma500/mrst: Replace WMs and chickenbits with values from EMGD drm/gma500/mrst: Add aux register writes to SDVO drm/gma500/mrst: Properly route oaktrail hdmi hooks drm/gma500/mrst: Add aux register writes when programming pipe drm/gma500/mrst: Add SDVO clock calculation drm/gma500: Add aux device support for gmbus drm/gma500: Add support for aux pci vdc device drm/gma500: Add chip specific sdvo masks drm/gma500: Add Minnowboard to the IS_MRST() macro
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c1
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c2
-rw-r--r--drivers/gpu/drm/gma500/intel_gmbus.c90
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_crtc.c433
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_device.c6
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_lvds.c30
-rw-r--r--drivers/gpu/drm/gma500/psb_device.c1
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c32
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h51
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo.c59
10 files changed, 448 insertions, 257 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index 162f686c532d..5a9a6a3063a8 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -634,6 +634,7 @@ const struct psb_ops cdv_chip_ops = {
634 .crtcs = 2, 634 .crtcs = 2,
635 .hdmi_mask = (1 << 0) | (1 << 1), 635 .hdmi_mask = (1 << 0) | (1 << 1),
636 .lvds_mask = (1 << 1), 636 .lvds_mask = (1 << 1),
637 .sdvo_mask = (1 << 0),
637 .cursor_needs_phys = 0, 638 .cursor_needs_phys = 0,
638 .sgx_offset = MRST_SGX_OFFSET, 639 .sgx_offset = MRST_SGX_OFFSET,
639 .chip_setup = cdv_chip_setup, 640 .chip_setup = cdv_chip_setup,
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 01dd7d225762..94b3fec22c28 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -714,7 +714,7 @@ static void psb_setup_outputs(struct drm_device *dev)
714 clone_mask = (1 << INTEL_OUTPUT_ANALOG); 714 clone_mask = (1 << INTEL_OUTPUT_ANALOG);
715 break; 715 break;
716 case INTEL_OUTPUT_SDVO: 716 case INTEL_OUTPUT_SDVO:
717 crtc_mask = ((1 << 0) | (1 << 1)); 717 crtc_mask = dev_priv->ops->sdvo_mask;
718 clone_mask = (1 << INTEL_OUTPUT_SDVO); 718 clone_mask = (1 << INTEL_OUTPUT_SDVO);
719 break; 719 break;
720 case INTEL_OUTPUT_LVDS: 720 case INTEL_OUTPUT_LVDS:
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c
index 62cd42e88f28..566d330aaeea 100644
--- a/drivers/gpu/drm/gma500/intel_gmbus.c
+++ b/drivers/gpu/drm/gma500/intel_gmbus.c
@@ -51,6 +51,9 @@
51#define wait_for(COND, MS) _wait_for(COND, MS, 1) 51#define wait_for(COND, MS) _wait_for(COND, MS, 1)
52#define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0) 52#define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0)
53 53
54#define GMBUS_REG_READ(reg) ioread32(dev_priv->gmbus_reg + (reg))
55#define GMBUS_REG_WRITE(reg, val) iowrite32((val), dev_priv->gmbus_reg + (reg))
56
54/* Intel GPIO access functions */ 57/* Intel GPIO access functions */
55 58
56#define I2C_RISEFALL_TIME 20 59#define I2C_RISEFALL_TIME 20
@@ -71,7 +74,8 @@ struct intel_gpio {
71void 74void
72gma_intel_i2c_reset(struct drm_device *dev) 75gma_intel_i2c_reset(struct drm_device *dev)
73{ 76{
74 REG_WRITE(GMBUS0, 0); 77 struct drm_psb_private *dev_priv = dev->dev_private;
78 GMBUS_REG_WRITE(GMBUS0, 0);
75} 79}
76 80
77static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable) 81static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable)
@@ -98,11 +102,10 @@ static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable)
98static u32 get_reserved(struct intel_gpio *gpio) 102static u32 get_reserved(struct intel_gpio *gpio)
99{ 103{
100 struct drm_psb_private *dev_priv = gpio->dev_priv; 104 struct drm_psb_private *dev_priv = gpio->dev_priv;
101 struct drm_device *dev = dev_priv->dev;
102 u32 reserved = 0; 105 u32 reserved = 0;
103 106
104 /* On most chips, these bits must be preserved in software. */ 107 /* On most chips, these bits must be preserved in software. */
105 reserved = REG_READ(gpio->reg) & 108 reserved = GMBUS_REG_READ(gpio->reg) &
106 (GPIO_DATA_PULLUP_DISABLE | 109 (GPIO_DATA_PULLUP_DISABLE |
107 GPIO_CLOCK_PULLUP_DISABLE); 110 GPIO_CLOCK_PULLUP_DISABLE);
108 111
@@ -113,29 +116,26 @@ static int get_clock(void *data)
113{ 116{
114 struct intel_gpio *gpio = data; 117 struct intel_gpio *gpio = data;
115 struct drm_psb_private *dev_priv = gpio->dev_priv; 118 struct drm_psb_private *dev_priv = gpio->dev_priv;
116 struct drm_device *dev = dev_priv->dev;
117 u32 reserved = get_reserved(gpio); 119 u32 reserved = get_reserved(gpio);
118 REG_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); 120 GMBUS_REG_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK);
119 REG_WRITE(gpio->reg, reserved); 121 GMBUS_REG_WRITE(gpio->reg, reserved);
120 return (REG_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; 122 return (GMBUS_REG_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0;
121} 123}
122 124
123static int get_data(void *data) 125static int get_data(void *data)
124{ 126{
125 struct intel_gpio *gpio = data; 127 struct intel_gpio *gpio = data;
126 struct drm_psb_private *dev_priv = gpio->dev_priv; 128 struct drm_psb_private *dev_priv = gpio->dev_priv;
127 struct drm_device *dev = dev_priv->dev;
128 u32 reserved = get_reserved(gpio); 129 u32 reserved = get_reserved(gpio);
129 REG_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); 130 GMBUS_REG_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK);
130 REG_WRITE(gpio->reg, reserved); 131 GMBUS_REG_WRITE(gpio->reg, reserved);
131 return (REG_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; 132 return (GMBUS_REG_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0;
132} 133}
133 134
134static void set_clock(void *data, int state_high) 135static void set_clock(void *data, int state_high)
135{ 136{
136 struct intel_gpio *gpio = data; 137 struct intel_gpio *gpio = data;
137 struct drm_psb_private *dev_priv = gpio->dev_priv; 138 struct drm_psb_private *dev_priv = gpio->dev_priv;
138 struct drm_device *dev = dev_priv->dev;
139 u32 reserved = get_reserved(gpio); 139 u32 reserved = get_reserved(gpio);
140 u32 clock_bits; 140 u32 clock_bits;
141 141
@@ -145,15 +145,14 @@ static void set_clock(void *data, int state_high)
145 clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | 145 clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
146 GPIO_CLOCK_VAL_MASK; 146 GPIO_CLOCK_VAL_MASK;
147 147
148 REG_WRITE(gpio->reg, reserved | clock_bits); 148 GMBUS_REG_WRITE(gpio->reg, reserved | clock_bits);
149 REG_READ(gpio->reg); /* Posting */ 149 GMBUS_REG_READ(gpio->reg); /* Posting */
150} 150}
151 151
152static void set_data(void *data, int state_high) 152static void set_data(void *data, int state_high)
153{ 153{
154 struct intel_gpio *gpio = data; 154 struct intel_gpio *gpio = data;
155 struct drm_psb_private *dev_priv = gpio->dev_priv; 155 struct drm_psb_private *dev_priv = gpio->dev_priv;
156 struct drm_device *dev = dev_priv->dev;
157 u32 reserved = get_reserved(gpio); 156 u32 reserved = get_reserved(gpio);
158 u32 data_bits; 157 u32 data_bits;
159 158
@@ -163,8 +162,8 @@ static void set_data(void *data, int state_high)
163 data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | 162 data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
164 GPIO_DATA_VAL_MASK; 163 GPIO_DATA_VAL_MASK;
165 164
166 REG_WRITE(gpio->reg, reserved | data_bits); 165 GMBUS_REG_WRITE(gpio->reg, reserved | data_bits);
167 REG_READ(gpio->reg); 166 GMBUS_REG_READ(gpio->reg);
168} 167}
169 168
170static struct i2c_adapter * 169static struct i2c_adapter *
@@ -251,7 +250,6 @@ gmbus_xfer(struct i2c_adapter *adapter,
251 struct intel_gmbus, 250 struct intel_gmbus,
252 adapter); 251 adapter);
253 struct drm_psb_private *dev_priv = adapter->algo_data; 252 struct drm_psb_private *dev_priv = adapter->algo_data;
254 struct drm_device *dev = dev_priv->dev;
255 int i, reg_offset; 253 int i, reg_offset;
256 254
257 if (bus->force_bit) 255 if (bus->force_bit)
@@ -260,28 +258,30 @@ gmbus_xfer(struct i2c_adapter *adapter,
260 258
261 reg_offset = 0; 259 reg_offset = 0;
262 260
263 REG_WRITE(GMBUS0 + reg_offset, bus->reg0); 261 GMBUS_REG_WRITE(GMBUS0 + reg_offset, bus->reg0);
264 262
265 for (i = 0; i < num; i++) { 263 for (i = 0; i < num; i++) {
266 u16 len = msgs[i].len; 264 u16 len = msgs[i].len;
267 u8 *buf = msgs[i].buf; 265 u8 *buf = msgs[i].buf;
268 266
269 if (msgs[i].flags & I2C_M_RD) { 267 if (msgs[i].flags & I2C_M_RD) {
270 REG_WRITE(GMBUS1 + reg_offset, 268 GMBUS_REG_WRITE(GMBUS1 + reg_offset,
271 GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | 269 GMBUS_CYCLE_WAIT |
272 (len << GMBUS_BYTE_COUNT_SHIFT) | 270 (i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
273 (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | 271 (len << GMBUS_BYTE_COUNT_SHIFT) |
274 GMBUS_SLAVE_READ | GMBUS_SW_RDY); 272 (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
275 REG_READ(GMBUS2+reg_offset); 273 GMBUS_SLAVE_READ | GMBUS_SW_RDY);
274 GMBUS_REG_READ(GMBUS2+reg_offset);
276 do { 275 do {
277 u32 val, loop = 0; 276 u32 val, loop = 0;
278 277
279 if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) 278 if (wait_for(GMBUS_REG_READ(GMBUS2 + reg_offset) &
279 (GMBUS_SATOER | GMBUS_HW_RDY), 50))
280 goto timeout; 280 goto timeout;
281 if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) 281 if (GMBUS_REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
282 goto clear_err; 282 goto clear_err;
283 283
284 val = REG_READ(GMBUS3 + reg_offset); 284 val = GMBUS_REG_READ(GMBUS3 + reg_offset);
285 do { 285 do {
286 *buf++ = val & 0xff; 286 *buf++ = val & 0xff;
287 val >>= 8; 287 val >>= 8;
@@ -295,18 +295,20 @@ gmbus_xfer(struct i2c_adapter *adapter,
295 val |= *buf++ << (8 * loop); 295 val |= *buf++ << (8 * loop);
296 } while (--len && ++loop < 4); 296 } while (--len && ++loop < 4);
297 297
298 REG_WRITE(GMBUS3 + reg_offset, val); 298 GMBUS_REG_WRITE(GMBUS3 + reg_offset, val);
299 REG_WRITE(GMBUS1 + reg_offset, 299 GMBUS_REG_WRITE(GMBUS1 + reg_offset,
300 (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) | 300 (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) |
301 (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | 301 (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) |
302 (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | 302 (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
303 GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); 303 GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
304 REG_READ(GMBUS2+reg_offset); 304 GMBUS_REG_READ(GMBUS2+reg_offset);
305 305
306 while (len) { 306 while (len) {
307 if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) 307 if (wait_for(GMBUS_REG_READ(GMBUS2 + reg_offset) &
308 (GMBUS_SATOER | GMBUS_HW_RDY), 50))
308 goto timeout; 309 goto timeout;
309 if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) 310 if (GMBUS_REG_READ(GMBUS2 + reg_offset) &
311 GMBUS_SATOER)
310 goto clear_err; 312 goto clear_err;
311 313
312 val = loop = 0; 314 val = loop = 0;
@@ -314,14 +316,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
314 val |= *buf++ << (8 * loop); 316 val |= *buf++ << (8 * loop);
315 } while (--len && ++loop < 4); 317 } while (--len && ++loop < 4);
316 318
317 REG_WRITE(GMBUS3 + reg_offset, val); 319 GMBUS_REG_WRITE(GMBUS3 + reg_offset, val);
318 REG_READ(GMBUS2+reg_offset); 320 GMBUS_REG_READ(GMBUS2+reg_offset);
319 } 321 }
320 } 322 }
321 323
322 if (i + 1 < num && wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) 324 if (i + 1 < num && wait_for(GMBUS_REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50))
323 goto timeout; 325 goto timeout;
324 if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) 326 if (GMBUS_REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
325 goto clear_err; 327 goto clear_err;
326 } 328 }
327 329
@@ -332,20 +334,20 @@ clear_err:
332 * of resetting the GMBUS controller and so clearing the 334 * of resetting the GMBUS controller and so clearing the
333 * BUS_ERROR raised by the slave's NAK. 335 * BUS_ERROR raised by the slave's NAK.
334 */ 336 */
335 REG_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); 337 GMBUS_REG_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT);
336 REG_WRITE(GMBUS1 + reg_offset, 0); 338 GMBUS_REG_WRITE(GMBUS1 + reg_offset, 0);
337 339
338done: 340done:
339 /* Mark the GMBUS interface as disabled. We will re-enable it at the 341 /* Mark the GMBUS interface as disabled. We will re-enable it at the
340 * start of the next xfer, till then let it sleep. 342 * start of the next xfer, till then let it sleep.
341 */ 343 */
342 REG_WRITE(GMBUS0 + reg_offset, 0); 344 GMBUS_REG_WRITE(GMBUS0 + reg_offset, 0);
343 return i; 345 return i;
344 346
345timeout: 347timeout:
346 DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n", 348 DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n",
347 bus->reg0 & 0xff, bus->adapter.name); 349 bus->reg0 & 0xff, bus->adapter.name);
348 REG_WRITE(GMBUS0 + reg_offset, 0); 350 GMBUS_REG_WRITE(GMBUS0 + reg_offset, 0);
349 351
350 /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ 352 /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
351 bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff); 353 bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff);
@@ -399,6 +401,11 @@ int gma_intel_setup_gmbus(struct drm_device *dev)
399 if (dev_priv->gmbus == NULL) 401 if (dev_priv->gmbus == NULL)
400 return -ENOMEM; 402 return -ENOMEM;
401 403
404 if (IS_MRST(dev))
405 dev_priv->gmbus_reg = dev_priv->aux_reg;
406 else
407 dev_priv->gmbus_reg = dev_priv->vdc_reg;
408
402 for (i = 0; i < GMBUS_NUM_PORTS; i++) { 409 for (i = 0; i < GMBUS_NUM_PORTS; i++) {
403 struct intel_gmbus *bus = &dev_priv->gmbus[i]; 410 struct intel_gmbus *bus = &dev_priv->gmbus[i];
404 411
@@ -487,6 +494,7 @@ void gma_intel_teardown_gmbus(struct drm_device *dev)
487 i2c_del_adapter(&bus->adapter); 494 i2c_del_adapter(&bus->adapter);
488 } 495 }
489 496
497 dev_priv->gmbus_reg = NULL; /* iounmap is done in driver_unload */
490 kfree(dev_priv->gmbus); 498 kfree(dev_priv->gmbus);
491 dev_priv->gmbus = NULL; 499 dev_priv->gmbus = NULL;
492} 500}
diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c
index 54c98962b73e..8195e8592107 100644
--- a/drivers/gpu/drm/gma500/oaktrail_crtc.c
+++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c
@@ -26,24 +26,10 @@
26#include "gma_display.h" 26#include "gma_display.h"
27#include "power.h" 27#include "power.h"
28 28
29struct psb_intel_range_t { 29#define MRST_LIMIT_LVDS_100L 0
30 int min, max; 30#define MRST_LIMIT_LVDS_83 1
31}; 31#define MRST_LIMIT_LVDS_100 2
32 32#define MRST_LIMIT_SDVO 3
33struct oaktrail_limit_t {
34 struct psb_intel_range_t dot, m, p1;
35};
36
37struct oaktrail_clock_t {
38 /* derived values */
39 int dot;
40 int m;
41 int p1;
42};
43
44#define MRST_LIMIT_LVDS_100L 0
45#define MRST_LIMIT_LVDS_83 1
46#define MRST_LIMIT_LVDS_100 2
47 33
48#define MRST_DOT_MIN 19750 34#define MRST_DOT_MIN 19750
49#define MRST_DOT_MAX 120000 35#define MRST_DOT_MAX 120000
@@ -57,21 +43,40 @@ struct oaktrail_clock_t {
57#define MRST_P1_MAX_0 7 43#define MRST_P1_MAX_0 7
58#define MRST_P1_MAX_1 8 44#define MRST_P1_MAX_1 8
59 45
60static const struct oaktrail_limit_t oaktrail_limits[] = { 46static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
47 struct drm_crtc *crtc, int target,
48 int refclk, struct gma_clock_t *best_clock);
49
50static bool mrst_sdvo_find_best_pll(const struct gma_limit_t *limit,
51 struct drm_crtc *crtc, int target,
52 int refclk, struct gma_clock_t *best_clock);
53
54static const struct gma_limit_t mrst_limits[] = {
61 { /* MRST_LIMIT_LVDS_100L */ 55 { /* MRST_LIMIT_LVDS_100L */
62 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, 56 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
63 .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L}, 57 .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L},
64 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, 58 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
59 .find_pll = mrst_lvds_find_best_pll,
65 }, 60 },
66 { /* MRST_LIMIT_LVDS_83L */ 61 { /* MRST_LIMIT_LVDS_83L */
67 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, 62 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
68 .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83}, 63 .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83},
69 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0}, 64 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0},
65 .find_pll = mrst_lvds_find_best_pll,
70 }, 66 },
71 { /* MRST_LIMIT_LVDS_100 */ 67 { /* MRST_LIMIT_LVDS_100 */
72 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, 68 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
73 .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100}, 69 .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100},
74 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, 70 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
71 .find_pll = mrst_lvds_find_best_pll,
72 },
73 { /* MRST_LIMIT_SDVO */
74 .vco = {.min = 1400000, .max = 2800000},
75 .n = {.min = 3, .max = 7},
76 .m = {.min = 80, .max = 137},
77 .p1 = {.min = 1, .max = 2},
78 .p2 = {.dot_limit = 200000, .p2_slow = 10, .p2_fast = 10},
79 .find_pll = mrst_sdvo_find_best_pll,
75 }, 80 },
76}; 81};
77 82
@@ -82,9 +87,10 @@ static const u32 oaktrail_m_converts[] = {
82 0x12, 0x09, 0x24, 0x32, 0x39, 0x1c, 87 0x12, 0x09, 0x24, 0x32, 0x39, 0x1c,
83}; 88};
84 89
85static const struct oaktrail_limit_t *oaktrail_limit(struct drm_crtc *crtc) 90static const struct gma_limit_t *mrst_limit(struct drm_crtc *crtc,
91 int refclk)
86{ 92{
87 const struct oaktrail_limit_t *limit = NULL; 93 const struct gma_limit_t *limit = NULL;
88 struct drm_device *dev = crtc->dev; 94 struct drm_device *dev = crtc->dev;
89 struct drm_psb_private *dev_priv = dev->dev_private; 95 struct drm_psb_private *dev_priv = dev->dev_private;
90 96
@@ -92,45 +98,100 @@ static const struct oaktrail_limit_t *oaktrail_limit(struct drm_crtc *crtc)
92 || gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) { 98 || gma_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
93 switch (dev_priv->core_freq) { 99 switch (dev_priv->core_freq) {
94 case 100: 100 case 100:
95 limit = &oaktrail_limits[MRST_LIMIT_LVDS_100L]; 101 limit = &mrst_limits[MRST_LIMIT_LVDS_100L];
96 break; 102 break;
97 case 166: 103 case 166:
98 limit = &oaktrail_limits[MRST_LIMIT_LVDS_83]; 104 limit = &mrst_limits[MRST_LIMIT_LVDS_83];
99 break; 105 break;
100 case 200: 106 case 200:
101 limit = &oaktrail_limits[MRST_LIMIT_LVDS_100]; 107 limit = &mrst_limits[MRST_LIMIT_LVDS_100];
102 break; 108 break;
103 } 109 }
110 } else if (gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
111 limit = &mrst_limits[MRST_LIMIT_SDVO];
104 } else { 112 } else {
105 limit = NULL; 113 limit = NULL;
106 dev_err(dev->dev, "oaktrail_limit Wrong display type.\n"); 114 dev_err(dev->dev, "mrst_limit Wrong display type.\n");
107 } 115 }
108 116
109 return limit; 117 return limit;
110} 118}
111 119
112/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ 120/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
113static void oaktrail_clock(int refclk, struct oaktrail_clock_t *clock) 121static void mrst_lvds_clock(int refclk, struct gma_clock_t *clock)
114{ 122{
115 clock->dot = (refclk * clock->m) / (14 * clock->p1); 123 clock->dot = (refclk * clock->m) / (14 * clock->p1);
116} 124}
117 125
118static void mrstPrintPll(char *prefix, struct oaktrail_clock_t *clock) 126static void mrst_print_pll(struct gma_clock_t *clock)
119{ 127{
120 pr_debug("%s: dotclock = %d, m = %d, p1 = %d.\n", 128 DRM_DEBUG_DRIVER("dotclock=%d, m=%d, m1=%d, m2=%d, n=%d, p1=%d, p2=%d\n",
121 prefix, clock->dot, clock->m, clock->p1); 129 clock->dot, clock->m, clock->m1, clock->m2, clock->n,
130 clock->p1, clock->p2);
131}
132
133static bool mrst_sdvo_find_best_pll(const struct gma_limit_t *limit,
134 struct drm_crtc *crtc, int target,
135 int refclk, struct gma_clock_t *best_clock)
136{
137 struct gma_clock_t clock;
138 u32 target_vco, actual_freq;
139 s32 freq_error, min_error = 100000;
140
141 memset(best_clock, 0, sizeof(*best_clock));
142
143 for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
144 for (clock.n = limit->n.min; clock.n <= limit->n.max;
145 clock.n++) {
146 for (clock.p1 = limit->p1.min;
147 clock.p1 <= limit->p1.max; clock.p1++) {
148 /* p2 value always stored in p2_slow on SDVO */
149 clock.p = clock.p1 * limit->p2.p2_slow;
150 target_vco = target * clock.p;
151
152 /* VCO will increase at this point so break */
153 if (target_vco > limit->vco.max)
154 break;
155
156 if (target_vco < limit->vco.min)
157 continue;
158
159 actual_freq = (refclk * clock.m) /
160 (clock.n * clock.p);
161 freq_error = 10000 -
162 ((target * 10000) / actual_freq);
163
164 if (freq_error < -min_error) {
165 /* freq_error will start to decrease at
166 this point so break */
167 break;
168 }
169
170 if (freq_error < 0)
171 freq_error = -freq_error;
172
173 if (freq_error < min_error) {
174 min_error = freq_error;
175 *best_clock = clock;
176 }
177 }
178 }
179 if (min_error == 0)
180 break;
181 }
182
183 return min_error == 0;
122} 184}
123 185
124/** 186/**
125 * Returns a set of divisors for the desired target clock with the given refclk, 187 * Returns a set of divisors for the desired target clock with the given refclk,
126 * or FALSE. Divisor values are the actual divisors for 188 * or FALSE. Divisor values are the actual divisors for
127 */ 189 */
128static bool 190static bool mrst_lvds_find_best_pll(const struct gma_limit_t *limit,
129mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk, 191 struct drm_crtc *crtc, int target,
130 struct oaktrail_clock_t *best_clock) 192 int refclk, struct gma_clock_t *best_clock)
131{ 193{
132 struct oaktrail_clock_t clock; 194 struct gma_clock_t clock;
133 const struct oaktrail_limit_t *limit = oaktrail_limit(crtc);
134 int err = target; 195 int err = target;
135 196
136 memset(best_clock, 0, sizeof(*best_clock)); 197 memset(best_clock, 0, sizeof(*best_clock));
@@ -140,7 +201,7 @@ mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
140 clock.p1++) { 201 clock.p1++) {
141 int this_err; 202 int this_err;
142 203
143 oaktrail_clock(refclk, &clock); 204 mrst_lvds_clock(refclk, &clock);
144 205
145 this_err = abs(clock.dot - target); 206 this_err = abs(clock.dot - target);
146 if (this_err < err) { 207 if (this_err < err) {
@@ -149,7 +210,6 @@ mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
149 } 210 }
150 } 211 }
151 } 212 }
152 dev_dbg(crtc->dev->dev, "mrstFindBestPLL err = %d.\n", err);
153 return err != target; 213 return err != target;
154} 214}
155 215
@@ -167,8 +227,10 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
167 int pipe = gma_crtc->pipe; 227 int pipe = gma_crtc->pipe;
168 const struct psb_offset *map = &dev_priv->regmap[pipe]; 228 const struct psb_offset *map = &dev_priv->regmap[pipe];
169 u32 temp; 229 u32 temp;
230 int i;
231 int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;
170 232
171 if (pipe == 1) { 233 if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
172 oaktrail_crtc_hdmi_dpms(crtc, mode); 234 oaktrail_crtc_hdmi_dpms(crtc, mode);
173 return; 235 return;
174 } 236 }
@@ -183,35 +245,45 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
183 case DRM_MODE_DPMS_ON: 245 case DRM_MODE_DPMS_ON:
184 case DRM_MODE_DPMS_STANDBY: 246 case DRM_MODE_DPMS_STANDBY:
185 case DRM_MODE_DPMS_SUSPEND: 247 case DRM_MODE_DPMS_SUSPEND:
186 /* Enable the DPLL */ 248 for (i = 0; i <= need_aux; i++) {
187 temp = REG_READ(map->dpll); 249 /* Enable the DPLL */
188 if ((temp & DPLL_VCO_ENABLE) == 0) { 250 temp = REG_READ_WITH_AUX(map->dpll, i);
189 REG_WRITE(map->dpll, temp); 251 if ((temp & DPLL_VCO_ENABLE) == 0) {
190 REG_READ(map->dpll); 252 REG_WRITE_WITH_AUX(map->dpll, temp, i);
191 /* Wait for the clocks to stabilize. */ 253 REG_READ_WITH_AUX(map->dpll, i);
192 udelay(150); 254 /* Wait for the clocks to stabilize. */
193 REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); 255 udelay(150);
194 REG_READ(map->dpll); 256 REG_WRITE_WITH_AUX(map->dpll,
195 /* Wait for the clocks to stabilize. */ 257 temp | DPLL_VCO_ENABLE, i);
196 udelay(150); 258 REG_READ_WITH_AUX(map->dpll, i);
197 REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); 259 /* Wait for the clocks to stabilize. */
198 REG_READ(map->dpll); 260 udelay(150);
199 /* Wait for the clocks to stabilize. */ 261 REG_WRITE_WITH_AUX(map->dpll,
200 udelay(150); 262 temp | DPLL_VCO_ENABLE, i);
201 } 263 REG_READ_WITH_AUX(map->dpll, i);
202 /* Enable the pipe */ 264 /* Wait for the clocks to stabilize. */
203 temp = REG_READ(map->conf); 265 udelay(150);
204 if ((temp & PIPEACONF_ENABLE) == 0) 266 }
205 REG_WRITE(map->conf, temp | PIPEACONF_ENABLE); 267
206 /* Enable the plane */ 268 /* Enable the pipe */
207 temp = REG_READ(map->cntr); 269 temp = REG_READ_WITH_AUX(map->conf, i);
208 if ((temp & DISPLAY_PLANE_ENABLE) == 0) { 270 if ((temp & PIPEACONF_ENABLE) == 0) {
209 REG_WRITE(map->cntr, 271 REG_WRITE_WITH_AUX(map->conf,
210 temp | DISPLAY_PLANE_ENABLE); 272 temp | PIPEACONF_ENABLE, i);
211 /* Flush the plane changes */ 273 }
212 REG_WRITE(map->base, REG_READ(map->base)); 274
213 } 275 /* Enable the plane */
276 temp = REG_READ_WITH_AUX(map->cntr, i);
277 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
278 REG_WRITE_WITH_AUX(map->cntr,
279 temp | DISPLAY_PLANE_ENABLE,
280 i);
281 /* Flush the plane changes */
282 REG_WRITE_WITH_AUX(map->base,
283 REG_READ_WITH_AUX(map->base, i), i);
284 }
214 285
286 }
215 gma_crtc_load_lut(crtc); 287 gma_crtc_load_lut(crtc);
216 288
217 /* Give the overlay scaler a chance to enable 289 /* Give the overlay scaler a chance to enable
@@ -223,48 +295,52 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode)
223 * if it's on this pipe */ 295 * if it's on this pipe */
224 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ 296 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
225 297
226 /* Disable the VGA plane that we never use */ 298 for (i = 0; i <= need_aux; i++) {
227 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 299 /* Disable the VGA plane that we never use */
228 /* Disable display plane */ 300 REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i);
229 temp = REG_READ(map->cntr); 301 /* Disable display plane */
230 if ((temp & DISPLAY_PLANE_ENABLE) != 0) { 302 temp = REG_READ_WITH_AUX(map->cntr, i);
231 REG_WRITE(map->cntr, 303 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
232 temp & ~DISPLAY_PLANE_ENABLE); 304 REG_WRITE_WITH_AUX(map->cntr,
233 /* Flush the plane changes */ 305 temp & ~DISPLAY_PLANE_ENABLE, i);
234 REG_WRITE(map->base, REG_READ(map->base)); 306 /* Flush the plane changes */
235 REG_READ(map->base); 307 REG_WRITE_WITH_AUX(map->base,
236 } 308 REG_READ(map->base), i);
309 REG_READ_WITH_AUX(map->base, i);
310 }
237 311
238 /* Next, disable display pipes */ 312 /* Next, disable display pipes */
239 temp = REG_READ(map->conf); 313 temp = REG_READ_WITH_AUX(map->conf, i);
240 if ((temp & PIPEACONF_ENABLE) != 0) { 314 if ((temp & PIPEACONF_ENABLE) != 0) {
241 REG_WRITE(map->conf, temp & ~PIPEACONF_ENABLE); 315 REG_WRITE_WITH_AUX(map->conf,
242 REG_READ(map->conf); 316 temp & ~PIPEACONF_ENABLE, i);
243 } 317 REG_READ_WITH_AUX(map->conf, i);
244 /* Wait for for the pipe disable to take effect. */ 318 }
245 gma_wait_for_vblank(dev); 319 /* Wait for for the pipe disable to take effect. */
320 gma_wait_for_vblank(dev);
321
322 temp = REG_READ_WITH_AUX(map->dpll, i);
323 if ((temp & DPLL_VCO_ENABLE) != 0) {
324 REG_WRITE_WITH_AUX(map->dpll,
325 temp & ~DPLL_VCO_ENABLE, i);
326 REG_READ_WITH_AUX(map->dpll, i);
327 }
246 328
247 temp = REG_READ(map->dpll); 329 /* Wait for the clocks to turn off. */
248 if ((temp & DPLL_VCO_ENABLE) != 0) { 330 udelay(150);
249 REG_WRITE(map->dpll, temp & ~DPLL_VCO_ENABLE);
250 REG_READ(map->dpll);
251 } 331 }
252
253 /* Wait for the clocks to turn off. */
254 udelay(150);
255 break; 332 break;
256 } 333 }
257 334
258 /*Set FIFO Watermarks*/ 335 /* Set FIFO Watermarks (values taken from EMGD) */
259 REG_WRITE(DSPARB, 0x3FFF); 336 REG_WRITE(DSPARB, 0x3f80);
260 REG_WRITE(DSPFW1, 0x3F88080A); 337 REG_WRITE(DSPFW1, 0x3f8f0404);
261 REG_WRITE(DSPFW2, 0x0b060808); 338 REG_WRITE(DSPFW2, 0x04040f04);
262 REG_WRITE(DSPFW3, 0x0); 339 REG_WRITE(DSPFW3, 0x0);
263 REG_WRITE(DSPFW4, 0x08030404); 340 REG_WRITE(DSPFW4, 0x04040404);
264 REG_WRITE(DSPFW5, 0x04040404); 341 REG_WRITE(DSPFW5, 0x04040404);
265 REG_WRITE(DSPFW6, 0x78); 342 REG_WRITE(DSPFW6, 0x78);
266 REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000); 343 REG_WRITE(DSPCHICKENBIT, REG_READ(DSPCHICKENBIT) | 0xc040);
267 /* Must write Bit 14 of the Chicken Bit Register */
268 344
269 gma_power_end(dev); 345 gma_power_end(dev);
270} 346}
@@ -297,7 +373,8 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
297 int pipe = gma_crtc->pipe; 373 int pipe = gma_crtc->pipe;
298 const struct psb_offset *map = &dev_priv->regmap[pipe]; 374 const struct psb_offset *map = &dev_priv->regmap[pipe];
299 int refclk = 0; 375 int refclk = 0;
300 struct oaktrail_clock_t clock; 376 struct gma_clock_t clock;
377 const struct gma_limit_t *limit;
301 u32 dpll = 0, fp = 0, dspcntr, pipeconf; 378 u32 dpll = 0, fp = 0, dspcntr, pipeconf;
302 bool ok, is_sdvo = false; 379 bool ok, is_sdvo = false;
303 bool is_lvds = false; 380 bool is_lvds = false;
@@ -306,8 +383,10 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
306 struct gma_encoder *gma_encoder = NULL; 383 struct gma_encoder *gma_encoder = NULL;
307 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; 384 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
308 struct drm_connector *connector; 385 struct drm_connector *connector;
386 int i;
387 int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0;
309 388
310 if (pipe == 1) 389 if (gma_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
311 return oaktrail_crtc_hdmi_mode_set(crtc, mode, adjusted_mode, x, y, old_fb); 390 return oaktrail_crtc_hdmi_mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
312 391
313 if (!gma_power_begin(dev, true)) 392 if (!gma_power_begin(dev, true))
@@ -340,15 +419,17 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
340 } 419 }
341 420
342 /* Disable the VGA plane that we never use */ 421 /* Disable the VGA plane that we never use */
343 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); 422 for (i = 0; i <= need_aux; i++)
423 REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i);
344 424
345 /* Disable the panel fitter if it was on our pipe */ 425 /* Disable the panel fitter if it was on our pipe */
346 if (oaktrail_panel_fitter_pipe(dev) == pipe) 426 if (oaktrail_panel_fitter_pipe(dev) == pipe)
347 REG_WRITE(PFIT_CONTROL, 0); 427 REG_WRITE(PFIT_CONTROL, 0);
348 428
349 REG_WRITE(map->src, 429 for (i = 0; i <= need_aux; i++) {
350 ((mode->crtc_hdisplay - 1) << 16) | 430 REG_WRITE_WITH_AUX(map->src, ((mode->crtc_hdisplay - 1) << 16) |
351 (mode->crtc_vdisplay - 1)); 431 (mode->crtc_vdisplay - 1), i);
432 }
352 433
353 if (gma_encoder) 434 if (gma_encoder)
354 drm_object_property_get_value(&connector->base, 435 drm_object_property_get_value(&connector->base,
@@ -365,35 +446,39 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
365 offsetY = (adjusted_mode->crtc_vdisplay - 446 offsetY = (adjusted_mode->crtc_vdisplay -
366 mode->crtc_vdisplay) / 2; 447 mode->crtc_vdisplay) / 2;
367 448
368 REG_WRITE(map->htotal, (mode->crtc_hdisplay - 1) | 449 for (i = 0; i <= need_aux; i++) {
369 ((adjusted_mode->crtc_htotal - 1) << 16)); 450 REG_WRITE_WITH_AUX(map->htotal, (mode->crtc_hdisplay - 1) |
370 REG_WRITE(map->vtotal, (mode->crtc_vdisplay - 1) | 451 ((adjusted_mode->crtc_htotal - 1) << 16), i);
371 ((adjusted_mode->crtc_vtotal - 1) << 16)); 452 REG_WRITE_WITH_AUX(map->vtotal, (mode->crtc_vdisplay - 1) |
372 REG_WRITE(map->hblank, 453 ((adjusted_mode->crtc_vtotal - 1) << 16), i);
373 (adjusted_mode->crtc_hblank_start - offsetX - 1) | 454 REG_WRITE_WITH_AUX(map->hblank,
374 ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); 455 (adjusted_mode->crtc_hblank_start - offsetX - 1) |
375 REG_WRITE(map->hsync, 456 ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16), i);
376 (adjusted_mode->crtc_hsync_start - offsetX - 1) | 457 REG_WRITE_WITH_AUX(map->hsync,
377 ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); 458 (adjusted_mode->crtc_hsync_start - offsetX - 1) |
378 REG_WRITE(map->vblank, 459 ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16), i);
379 (adjusted_mode->crtc_vblank_start - offsetY - 1) | 460 REG_WRITE_WITH_AUX(map->vblank,
380 ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); 461 (adjusted_mode->crtc_vblank_start - offsetY - 1) |
381 REG_WRITE(map->vsync, 462 ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16), i);
382 (adjusted_mode->crtc_vsync_start - offsetY - 1) | 463 REG_WRITE_WITH_AUX(map->vsync,
383 ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); 464 (adjusted_mode->crtc_vsync_start - offsetY - 1) |
465 ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16), i);
466 }
384 } else { 467 } else {
385 REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) | 468 for (i = 0; i <= need_aux; i++) {
386 ((adjusted_mode->crtc_htotal - 1) << 16)); 469 REG_WRITE_WITH_AUX(map->htotal, (adjusted_mode->crtc_hdisplay - 1) |
387 REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) | 470 ((adjusted_mode->crtc_htotal - 1) << 16), i);
388 ((adjusted_mode->crtc_vtotal - 1) << 16)); 471 REG_WRITE_WITH_AUX(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) |
389 REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) | 472 ((adjusted_mode->crtc_vtotal - 1) << 16), i);
390 ((adjusted_mode->crtc_hblank_end - 1) << 16)); 473 REG_WRITE_WITH_AUX(map->hblank, (adjusted_mode->crtc_hblank_start - 1) |
391 REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) | 474 ((adjusted_mode->crtc_hblank_end - 1) << 16), i);
392 ((adjusted_mode->crtc_hsync_end - 1) << 16)); 475 REG_WRITE_WITH_AUX(map->hsync, (adjusted_mode->crtc_hsync_start - 1) |
393 REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) | 476 ((adjusted_mode->crtc_hsync_end - 1) << 16), i);
394 ((adjusted_mode->crtc_vblank_end - 1) << 16)); 477 REG_WRITE_WITH_AUX(map->vblank, (adjusted_mode->crtc_vblank_start - 1) |
395 REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) | 478 ((adjusted_mode->crtc_vblank_end - 1) << 16), i);
396 ((adjusted_mode->crtc_vsync_end - 1) << 16)); 479 REG_WRITE_WITH_AUX(map->vsync, (adjusted_mode->crtc_vsync_start - 1) |
480 ((adjusted_mode->crtc_vsync_end - 1) << 16), i);
481 }
397 } 482 }
398 483
399 /* Flush the plane changes */ 484 /* Flush the plane changes */
@@ -418,21 +503,30 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
418 if (is_mipi) 503 if (is_mipi)
419 goto oaktrail_crtc_mode_set_exit; 504 goto oaktrail_crtc_mode_set_exit;
420 505
421 refclk = dev_priv->core_freq * 1000;
422 506
423 dpll = 0; /*BIT16 = 0 for 100MHz reference */ 507 dpll = 0; /*BIT16 = 0 for 100MHz reference */
424 508
425 ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock); 509 refclk = is_sdvo ? 96000 : dev_priv->core_freq * 1000;
510 limit = mrst_limit(crtc, refclk);
511 ok = limit->find_pll(limit, crtc, adjusted_mode->clock,
512 refclk, &clock);
426 513
427 if (!ok) { 514 if (is_sdvo) {
428 dev_dbg(dev->dev, "mrstFindBestPLL fail in oaktrail_crtc_mode_set.\n"); 515 /* Convert calculated values to register values */
429 } else { 516 clock.p1 = (1L << (clock.p1 - 1));
430 dev_dbg(dev->dev, "oaktrail_crtc_mode_set pixel clock = %d," 517 clock.m -= 2;
431 "m = %x, p1 = %x.\n", clock.dot, clock.m, 518 clock.n = (1L << (clock.n - 1));
432 clock.p1);
433 } 519 }
434 520
435 fp = oaktrail_m_converts[(clock.m - MRST_M_MIN)] << 8; 521 if (!ok)
522 DRM_ERROR("Failed to find proper PLL settings");
523
524 mrst_print_pll(&clock);
525
526 if (is_sdvo)
527 fp = clock.n << 16 | clock.m;
528 else
529 fp = oaktrail_m_converts[(clock.m - MRST_M_MIN)] << 8;
436 530
437 dpll |= DPLL_VGA_MODE_DIS; 531 dpll |= DPLL_VGA_MODE_DIS;
438 532
@@ -456,38 +550,43 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc,
456 550
457 551
458 /* compute bitmask from p1 value */ 552 /* compute bitmask from p1 value */
459 dpll |= (1 << (clock.p1 - 2)) << 17; 553 if (is_sdvo)
554 dpll |= clock.p1 << 16; // dpll |= (1 << (clock.p1 - 1)) << 16;
555 else
556 dpll |= (1 << (clock.p1 - 2)) << 17;
460 557
461 dpll |= DPLL_VCO_ENABLE; 558 dpll |= DPLL_VCO_ENABLE;
462 559
463 mrstPrintPll("chosen", &clock);
464
465 if (dpll & DPLL_VCO_ENABLE) { 560 if (dpll & DPLL_VCO_ENABLE) {
466 REG_WRITE(map->fp0, fp); 561 for (i = 0; i <= need_aux; i++) {
467 REG_WRITE(map->dpll, dpll & ~DPLL_VCO_ENABLE); 562 REG_WRITE_WITH_AUX(map->fp0, fp, i);
468 REG_READ(map->dpll); 563 REG_WRITE_WITH_AUX(map->dpll, dpll & ~DPLL_VCO_ENABLE, i);
469 /* Check the DPLLA lock bit PIPEACONF[29] */ 564 REG_READ_WITH_AUX(map->dpll, i);
470 udelay(150); 565 /* Check the DPLLA lock bit PIPEACONF[29] */
566 udelay(150);
567 }
471 } 568 }
472 569
473 REG_WRITE(map->fp0, fp); 570 for (i = 0; i <= need_aux; i++) {
474 REG_WRITE(map->dpll, dpll); 571 REG_WRITE_WITH_AUX(map->fp0, fp, i);
475 REG_READ(map->dpll); 572 REG_WRITE_WITH_AUX(map->dpll, dpll, i);
476 /* Wait for the clocks to stabilize. */ 573 REG_READ_WITH_AUX(map->dpll, i);
477 udelay(150); 574 /* Wait for the clocks to stabilize. */
575 udelay(150);
478 576
479 /* write it again -- the BIOS does, after all */ 577 /* write it again -- the BIOS does, after all */
480 REG_WRITE(map->dpll, dpll); 578 REG_WRITE_WITH_AUX(map->dpll, dpll, i);
481 REG_READ(map->dpll); 579 REG_READ_WITH_AUX(map->dpll, i);
482 /* Wait for the clocks to stabilize. */ 580 /* Wait for the clocks to stabilize. */
483 udelay(150); 581 udelay(150);
484 582
485 REG_WRITE(map->conf, pipeconf); 583 REG_WRITE_WITH_AUX(map->conf, pipeconf, i);
486 REG_READ(map->conf); 584 REG_READ_WITH_AUX(map->conf, i);
487 gma_wait_for_vblank(dev); 585 gma_wait_for_vblank(dev);
488 586
489 REG_WRITE(map->cntr, dspcntr); 587 REG_WRITE_WITH_AUX(map->cntr, dspcntr, i);
490 gma_wait_for_vblank(dev); 588 gma_wait_for_vblank(dev);
589 }
491 590
492oaktrail_crtc_mode_set_exit: 591oaktrail_crtc_mode_set_exit:
493 gma_power_end(dev); 592 gma_power_end(dev);
@@ -565,3 +664,9 @@ const struct drm_crtc_helper_funcs oaktrail_helper_funcs = {
565 .commit = gma_crtc_commit, 664 .commit = gma_crtc_commit,
566}; 665};
567 666
667/* Not used yet */
668const struct gma_clock_funcs mrst_clock_funcs = {
669 .clock = mrst_lvds_clock,
670 .limit = mrst_limit,
671 .pll_is_valid = gma_pll_is_valid,
672};
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c
index 08747fd7105c..27d3875d895b 100644
--- a/drivers/gpu/drm/gma500/oaktrail_device.c
+++ b/drivers/gpu/drm/gma500/oaktrail_device.c
@@ -40,6 +40,9 @@ static int oaktrail_output_init(struct drm_device *dev)
40 dev_err(dev->dev, "DSI is not supported\n"); 40 dev_err(dev->dev, "DSI is not supported\n");
41 if (dev_priv->hdmi_priv) 41 if (dev_priv->hdmi_priv)
42 oaktrail_hdmi_init(dev, &dev_priv->mode_dev); 42 oaktrail_hdmi_init(dev, &dev_priv->mode_dev);
43
44 psb_intel_sdvo_init(dev, SDVOB);
45
43 return 0; 46 return 0;
44} 47}
45 48
@@ -526,6 +529,7 @@ static int oaktrail_chip_setup(struct drm_device *dev)
526 psb_intel_opregion_init(dev); 529 psb_intel_opregion_init(dev);
527 psb_intel_init_bios(dev); 530 psb_intel_init_bios(dev);
528 } 531 }
532 gma_intel_setup_gmbus(dev);
529 oaktrail_hdmi_setup(dev); 533 oaktrail_hdmi_setup(dev);
530 return 0; 534 return 0;
531} 535}
@@ -534,6 +538,7 @@ static void oaktrail_teardown(struct drm_device *dev)
534{ 538{
535 struct drm_psb_private *dev_priv = dev->dev_private; 539 struct drm_psb_private *dev_priv = dev->dev_private;
536 540
541 gma_intel_teardown_gmbus(dev);
537 oaktrail_hdmi_teardown(dev); 542 oaktrail_hdmi_teardown(dev);
538 if (!dev_priv->has_gct) 543 if (!dev_priv->has_gct)
539 psb_intel_destroy_bios(dev); 544 psb_intel_destroy_bios(dev);
@@ -546,6 +551,7 @@ const struct psb_ops oaktrail_chip_ops = {
546 .crtcs = 2, 551 .crtcs = 2,
547 .hdmi_mask = (1 << 1), 552 .hdmi_mask = (1 << 1),
548 .lvds_mask = (1 << 0), 553 .lvds_mask = (1 << 0),
554 .sdvo_mask = (1 << 1),
549 .cursor_needs_phys = 0, 555 .cursor_needs_phys = 0,
550 .sgx_offset = MRST_SGX_OFFSET, 556 .sgx_offset = MRST_SGX_OFFSET,
551 557
diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c
index e77d7214fca4..4c17c93d8d10 100644
--- a/drivers/gpu/drm/gma500/oaktrail_lvds.c
+++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c
@@ -218,30 +218,6 @@ static const struct drm_encoder_helper_funcs oaktrail_lvds_helper_funcs = {
218 .commit = oaktrail_lvds_commit, 218 .commit = oaktrail_lvds_commit,
219}; 219};
220 220
221static struct drm_display_mode lvds_configuration_modes[] = {
222 /* hard coded fixed mode for TPO LTPS LPJ040K001A */
223 { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 33264, 800, 836,
224 846, 1056, 0, 480, 489, 491, 525, 0, 0) },
225 /* hard coded fixed mode for LVDS 800x480 */
226 { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 30994, 800, 801,
227 802, 1024, 0, 480, 481, 482, 525, 0, 0) },
228 /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
229 { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072,
230 1104, 1184, 0, 600, 603, 604, 608, 0, 0) },
231 /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
232 { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104,
233 1136, 1184, 0, 600, 603, 604, 608, 0, 0) },
234 /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
235 { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124,
236 1204, 1312, 0, 600, 607, 610, 621, 0, 0) },
237 /* hard coded fixed mode for LVDS 1024x768 */
238 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
239 1184, 1344, 0, 768, 771, 777, 806, 0, 0) },
240 /* hard coded fixed mode for LVDS 1366x768 */
241 { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430,
242 1558, 1664, 0, 768, 769, 770, 776, 0, 0) },
243};
244
245/* Returns the panel fixed mode from configuration. */ 221/* Returns the panel fixed mode from configuration. */
246 222
247static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev, 223static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev,
@@ -303,10 +279,10 @@ static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev,
303 mode_dev->panel_fixed_mode = 279 mode_dev->panel_fixed_mode =
304 drm_mode_duplicate(dev, 280 drm_mode_duplicate(dev,
305 dev_priv->lfp_lvds_vbt_mode); 281 dev_priv->lfp_lvds_vbt_mode);
306 /* Then guess */ 282
283 /* If we still got no mode then bail */
307 if (mode_dev->panel_fixed_mode == NULL) 284 if (mode_dev->panel_fixed_mode == NULL)
308 mode_dev->panel_fixed_mode 285 return;
309 = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
310 286
311 drm_mode_set_name(mode_dev->panel_fixed_mode); 287 drm_mode_set_name(mode_dev->panel_fixed_mode);
312 drm_mode_set_crtcinfo(mode_dev->panel_fixed_mode, 0); 288 drm_mode_set_crtcinfo(mode_dev->panel_fixed_mode, 0);
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c
index 697678619bd1..23fb33f1471b 100644
--- a/drivers/gpu/drm/gma500/psb_device.c
+++ b/drivers/gpu/drm/gma500/psb_device.c
@@ -373,6 +373,7 @@ const struct psb_ops psb_chip_ops = {
373 .crtcs = 2, 373 .crtcs = 2,
374 .hdmi_mask = (1 << 0), 374 .hdmi_mask = (1 << 0),
375 .lvds_mask = (1 << 1), 375 .lvds_mask = (1 << 1),
376 .sdvo_mask = (1 << 0),
376 .cursor_needs_phys = 1, 377 .cursor_needs_phys = 1,
377 .sgx_offset = PSB_SGX_OFFSET, 378 .sgx_offset = PSB_SGX_OFFSET,
378 .chip_setup = psb_chip_setup, 379 .chip_setup = psb_chip_setup,
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 679f95313c29..1199180667c9 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -251,6 +251,12 @@ static int psb_driver_unload(struct drm_device *dev)
251 iounmap(dev_priv->sgx_reg); 251 iounmap(dev_priv->sgx_reg);
252 dev_priv->sgx_reg = NULL; 252 dev_priv->sgx_reg = NULL;
253 } 253 }
254 if (dev_priv->aux_reg) {
255 iounmap(dev_priv->aux_reg);
256 dev_priv->aux_reg = NULL;
257 }
258 if (dev_priv->aux_pdev)
259 pci_dev_put(dev_priv->aux_pdev);
254 260
255 /* Destroy VBT data */ 261 /* Destroy VBT data */
256 psb_intel_destroy_bios(dev); 262 psb_intel_destroy_bios(dev);
@@ -266,7 +272,7 @@ static int psb_driver_unload(struct drm_device *dev)
266static int psb_driver_load(struct drm_device *dev, unsigned long chipset) 272static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
267{ 273{
268 struct drm_psb_private *dev_priv; 274 struct drm_psb_private *dev_priv;
269 unsigned long resource_start; 275 unsigned long resource_start, resource_len;
270 unsigned long irqflags; 276 unsigned long irqflags;
271 int ret = -ENOMEM; 277 int ret = -ENOMEM;
272 struct drm_connector *connector; 278 struct drm_connector *connector;
@@ -296,6 +302,30 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
296 if (!dev_priv->sgx_reg) 302 if (!dev_priv->sgx_reg)
297 goto out_err; 303 goto out_err;
298 304
305 if (IS_MRST(dev)) {
306 dev_priv->aux_pdev = pci_get_bus_and_slot(0, PCI_DEVFN(3, 0));
307
308 if (dev_priv->aux_pdev) {
309 resource_start = pci_resource_start(dev_priv->aux_pdev,
310 PSB_AUX_RESOURCE);
311 resource_len = pci_resource_len(dev_priv->aux_pdev,
312 PSB_AUX_RESOURCE);
313 dev_priv->aux_reg = ioremap_nocache(resource_start,
314 resource_len);
315 if (!dev_priv->aux_reg)
316 goto out_err;
317
318 DRM_DEBUG_KMS("Found aux vdc");
319 } else {
320 /* Couldn't find the aux vdc so map to primary vdc */
321 dev_priv->aux_reg = dev_priv->vdc_reg;
322 DRM_DEBUG_KMS("Couldn't find aux pci device");
323 }
324 dev_priv->gmbus_reg = dev_priv->aux_reg;
325 } else {
326 dev_priv->gmbus_reg = dev_priv->vdc_reg;
327 }
328
299 psb_intel_opregion_setup(dev); 329 psb_intel_opregion_setup(dev);
300 330
301 ret = dev_priv->ops->chip_setup(dev); 331 ret = dev_priv->ops->chip_setup(dev);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 0bab46bd73d2..b59e6588c343 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -45,7 +45,7 @@ enum {
45}; 45};
46 46
47#define IS_PSB(dev) (((dev)->pdev->device & 0xfffe) == 0x8108) 47#define IS_PSB(dev) (((dev)->pdev->device & 0xfffe) == 0x8108)
48#define IS_MRST(dev) (((dev)->pdev->device & 0xfffc) == 0x4100) 48#define IS_MRST(dev) (((dev)->pdev->device & 0xfff0) == 0x4100)
49#define IS_MFLD(dev) (((dev)->pdev->device & 0xfff8) == 0x0130) 49#define IS_MFLD(dev) (((dev)->pdev->device & 0xfff8) == 0x0130)
50#define IS_CDV(dev) (((dev)->pdev->device & 0xfff0) == 0x0be0) 50#define IS_CDV(dev) (((dev)->pdev->device & 0xfff0) == 0x0be0)
51 51
@@ -75,6 +75,7 @@ enum {
75 * PCI resource identifiers 75 * PCI resource identifiers
76 */ 76 */
77#define PSB_MMIO_RESOURCE 0 77#define PSB_MMIO_RESOURCE 0
78#define PSB_AUX_RESOURCE 0
78#define PSB_GATT_RESOURCE 2 79#define PSB_GATT_RESOURCE 2
79#define PSB_GTT_RESOURCE 3 80#define PSB_GTT_RESOURCE 3
80/* 81/*
@@ -455,6 +456,7 @@ struct psb_ops;
455 456
456struct drm_psb_private { 457struct drm_psb_private {
457 struct drm_device *dev; 458 struct drm_device *dev;
459 struct pci_dev *aux_pdev; /* Currently only used by mrst */
458 const struct psb_ops *ops; 460 const struct psb_ops *ops;
459 const struct psb_offset *regmap; 461 const struct psb_offset *regmap;
460 462
@@ -486,6 +488,7 @@ struct drm_psb_private {
486 488
487 uint8_t __iomem *sgx_reg; 489 uint8_t __iomem *sgx_reg;
488 uint8_t __iomem *vdc_reg; 490 uint8_t __iomem *vdc_reg;
491 uint8_t __iomem *aux_reg; /* Auxillary vdc pipe regs */
489 uint32_t gatt_free_offset; 492 uint32_t gatt_free_offset;
490 493
491 /* 494 /*
@@ -532,6 +535,7 @@ struct drm_psb_private {
532 535
533 /* gmbus */ 536 /* gmbus */
534 struct intel_gmbus *gmbus; 537 struct intel_gmbus *gmbus;
538 uint8_t __iomem *gmbus_reg;
535 539
536 /* Used by SDVO */ 540 /* Used by SDVO */
537 int crt_ddc_pin; 541 int crt_ddc_pin;
@@ -672,6 +676,7 @@ struct psb_ops {
672 int sgx_offset; /* Base offset of SGX device */ 676 int sgx_offset; /* Base offset of SGX device */
673 int hdmi_mask; /* Mask of HDMI CRTCs */ 677 int hdmi_mask; /* Mask of HDMI CRTCs */
674 int lvds_mask; /* Mask of LVDS CRTCs */ 678 int lvds_mask; /* Mask of LVDS CRTCs */
679 int sdvo_mask; /* Mask of SDVO CRTCs */
675 int cursor_needs_phys; /* If cursor base reg need physical address */ 680 int cursor_needs_phys; /* If cursor base reg need physical address */
676 681
677 /* Sub functions */ 682 /* Sub functions */
@@ -927,16 +932,58 @@ static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg)
927 return ioread32(dev_priv->vdc_reg + reg); 932 return ioread32(dev_priv->vdc_reg + reg);
928} 933}
929 934
935static inline uint32_t REGISTER_READ_AUX(struct drm_device *dev, uint32_t reg)
936{
937 struct drm_psb_private *dev_priv = dev->dev_private;
938 return ioread32(dev_priv->aux_reg + reg);
939}
940
930#define REG_READ(reg) REGISTER_READ(dev, (reg)) 941#define REG_READ(reg) REGISTER_READ(dev, (reg))
942#define REG_READ_AUX(reg) REGISTER_READ_AUX(dev, (reg))
943
944/* Useful for post reads */
945static inline uint32_t REGISTER_READ_WITH_AUX(struct drm_device *dev,
946 uint32_t reg, int aux)
947{
948 uint32_t val;
949
950 if (aux)
951 val = REG_READ_AUX(reg);
952 else
953 val = REG_READ(reg);
954
955 return val;
956}
957
958#define REG_READ_WITH_AUX(reg, aux) REGISTER_READ_WITH_AUX(dev, (reg), (aux))
931 959
932static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg, 960static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
933 uint32_t val) 961 uint32_t val)
934{ 962{
935 struct drm_psb_private *dev_priv = dev->dev_private; 963 struct drm_psb_private *dev_priv = dev->dev_private;
936 iowrite32((val), dev_priv->vdc_reg + (reg)); 964 iowrite32((val), dev_priv->vdc_reg + (reg));
937} 965}
938 966
967static inline void REGISTER_WRITE_AUX(struct drm_device *dev, uint32_t reg,
968 uint32_t val)
969{
970 struct drm_psb_private *dev_priv = dev->dev_private;
971 iowrite32((val), dev_priv->aux_reg + (reg));
972}
973
939#define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val)) 974#define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val))
975#define REG_WRITE_AUX(reg, val) REGISTER_WRITE_AUX(dev, (reg), (val))
976
977static inline void REGISTER_WRITE_WITH_AUX(struct drm_device *dev, uint32_t reg,
978 uint32_t val, int aux)
979{
980 if (aux)
981 REG_WRITE_AUX(reg, val);
982 else
983 REG_WRITE(reg, val);
984}
985
986#define REG_WRITE_WITH_AUX(reg, val, aux) REGISTER_WRITE_WITH_AUX(dev, (reg), (val), (aux))
940 987
941static inline void REGISTER_WRITE16(struct drm_device *dev, 988static inline void REGISTER_WRITE16(struct drm_device *dev,
942 uint32_t reg, uint32_t val) 989 uint32_t reg, uint32_t val)
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index 6f01cdf5e125..07d3a9e6d79b 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -228,24 +228,26 @@ static void psb_intel_sdvo_write_sdvox(struct psb_intel_sdvo *psb_intel_sdvo, u3
228{ 228{
229 struct drm_device *dev = psb_intel_sdvo->base.base.dev; 229 struct drm_device *dev = psb_intel_sdvo->base.base.dev;
230 u32 bval = val, cval = val; 230 u32 bval = val, cval = val;
231 int i; 231 int i, j;
232 int need_aux = IS_MRST(dev) ? 1 : 0;
232 233
233 if (psb_intel_sdvo->sdvo_reg == SDVOB) { 234 for (j = 0; j <= need_aux; j++) {
234 cval = REG_READ(SDVOC); 235 if (psb_intel_sdvo->sdvo_reg == SDVOB)
235 } else { 236 cval = REG_READ_WITH_AUX(SDVOC, j);
236 bval = REG_READ(SDVOB); 237 else
237 } 238 bval = REG_READ_WITH_AUX(SDVOB, j);
238 /* 239
239 * Write the registers twice for luck. Sometimes, 240 /*
240 * writing them only once doesn't appear to 'stick'. 241 * Write the registers twice for luck. Sometimes,
241 * The BIOS does this too. Yay, magic 242 * writing them only once doesn't appear to 'stick'.
242 */ 243 * The BIOS does this too. Yay, magic
243 for (i = 0; i < 2; i++) 244 */
244 { 245 for (i = 0; i < 2; i++) {
245 REG_WRITE(SDVOB, bval); 246 REG_WRITE_WITH_AUX(SDVOB, bval, j);
246 REG_READ(SDVOB); 247 REG_READ_WITH_AUX(SDVOB, j);
247 REG_WRITE(SDVOC, cval); 248 REG_WRITE_WITH_AUX(SDVOC, cval, j);
248 REG_READ(SDVOC); 249 REG_READ_WITH_AUX(SDVOC, j);
250 }
249 } 251 }
250} 252}
251 253
@@ -995,6 +997,7 @@ static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
995 struct psb_intel_sdvo_dtd input_dtd; 997 struct psb_intel_sdvo_dtd input_dtd;
996 int pixel_multiplier = psb_intel_mode_get_pixel_multiplier(adjusted_mode); 998 int pixel_multiplier = psb_intel_mode_get_pixel_multiplier(adjusted_mode);
997 int rate; 999 int rate;
1000 int need_aux = IS_MRST(dev) ? 1 : 0;
998 1001
999 if (!mode) 1002 if (!mode)
1000 return; 1003 return;
@@ -1060,7 +1063,11 @@ static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
1060 return; 1063 return;
1061 1064
1062 /* Set the SDVO control regs. */ 1065 /* Set the SDVO control regs. */
1063 sdvox = REG_READ(psb_intel_sdvo->sdvo_reg); 1066 if (need_aux)
1067 sdvox = REG_READ_AUX(psb_intel_sdvo->sdvo_reg);
1068 else
1069 sdvox = REG_READ(psb_intel_sdvo->sdvo_reg);
1070
1064 switch (psb_intel_sdvo->sdvo_reg) { 1071 switch (psb_intel_sdvo->sdvo_reg) {
1065 case SDVOB: 1072 case SDVOB:
1066 sdvox &= SDVOB_PRESERVE_MASK; 1073 sdvox &= SDVOB_PRESERVE_MASK;
@@ -1090,6 +1097,8 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
1090 struct drm_device *dev = encoder->dev; 1097 struct drm_device *dev = encoder->dev;
1091 struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); 1098 struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder);
1092 u32 temp; 1099 u32 temp;
1100 int i;
1101 int need_aux = IS_MRST(dev) ? 1 : 0;
1093 1102
1094 switch (mode) { 1103 switch (mode) {
1095 case DRM_MODE_DPMS_ON: 1104 case DRM_MODE_DPMS_ON:
@@ -1108,19 +1117,27 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
1108 psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode); 1117 psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode);
1109 1118
1110 if (mode == DRM_MODE_DPMS_OFF) { 1119 if (mode == DRM_MODE_DPMS_OFF) {
1111 temp = REG_READ(psb_intel_sdvo->sdvo_reg); 1120 if (need_aux)
1121 temp = REG_READ_AUX(psb_intel_sdvo->sdvo_reg);
1122 else
1123 temp = REG_READ(psb_intel_sdvo->sdvo_reg);
1124
1112 if ((temp & SDVO_ENABLE) != 0) { 1125 if ((temp & SDVO_ENABLE) != 0) {
1113 psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp & ~SDVO_ENABLE); 1126 psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp & ~SDVO_ENABLE);
1114 } 1127 }
1115 } 1128 }
1116 } else { 1129 } else {
1117 bool input1, input2; 1130 bool input1, input2;
1118 int i;
1119 u8 status; 1131 u8 status;
1120 1132
1121 temp = REG_READ(psb_intel_sdvo->sdvo_reg); 1133 if (need_aux)
1134 temp = REG_READ_AUX(psb_intel_sdvo->sdvo_reg);
1135 else
1136 temp = REG_READ(psb_intel_sdvo->sdvo_reg);
1137
1122 if ((temp & SDVO_ENABLE) == 0) 1138 if ((temp & SDVO_ENABLE) == 0)
1123 psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp | SDVO_ENABLE); 1139 psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp | SDVO_ENABLE);
1140
1124 for (i = 0; i < 2; i++) 1141 for (i = 0; i < 2; i++)
1125 gma_wait_for_vblank(dev); 1142 gma_wait_for_vblank(dev);
1126 1143