Commit fb8e34d5 authored by Patrik Jakobsson's avatar Patrik Jakobsson

drm/gma500/mrst: Add aux register writes to SDVO

This turned out to be tricky. Writing to SDVOB on the primary vdc also
writes to SDVOB on the aux vdc, but reading it back on the primary vdc
always fails. Basically we never read from the primary vdc since we
will end up trashing the aux vdc.
Signed-off-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
parent 5aac7883
...@@ -228,24 +228,26 @@ static void psb_intel_sdvo_write_sdvox(struct psb_intel_sdvo *psb_intel_sdvo, u3 ...@@ -228,24 +228,26 @@ static void psb_intel_sdvo_write_sdvox(struct psb_intel_sdvo *psb_intel_sdvo, u3
{ {
struct drm_device *dev = psb_intel_sdvo->base.base.dev; struct drm_device *dev = psb_intel_sdvo->base.base.dev;
u32 bval = val, cval = val; u32 bval = val, cval = val;
int i; int i, j;
int need_aux = IS_MRST(dev) ? 1 : 0;
for (j = 0; j <= need_aux; j++) {
if (psb_intel_sdvo->sdvo_reg == SDVOB)
cval = REG_READ_WITH_AUX(SDVOC, j);
else
bval = REG_READ_WITH_AUX(SDVOB, j);
if (psb_intel_sdvo->sdvo_reg == SDVOB) {
cval = REG_READ(SDVOC);
} else {
bval = REG_READ(SDVOB);
}
/* /*
* Write the registers twice for luck. Sometimes, * Write the registers twice for luck. Sometimes,
* writing them only once doesn't appear to 'stick'. * writing them only once doesn't appear to 'stick'.
* The BIOS does this too. Yay, magic * The BIOS does this too. Yay, magic
*/ */
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++) {
{ REG_WRITE_WITH_AUX(SDVOB, bval, j);
REG_WRITE(SDVOB, bval); REG_READ_WITH_AUX(SDVOB, j);
REG_READ(SDVOB); REG_WRITE_WITH_AUX(SDVOC, cval, j);
REG_WRITE(SDVOC, cval); REG_READ_WITH_AUX(SDVOC, j);
REG_READ(SDVOC); }
} }
} }
...@@ -995,6 +997,7 @@ static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder, ...@@ -995,6 +997,7 @@ static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
struct psb_intel_sdvo_dtd input_dtd; struct psb_intel_sdvo_dtd input_dtd;
int pixel_multiplier = psb_intel_mode_get_pixel_multiplier(adjusted_mode); int pixel_multiplier = psb_intel_mode_get_pixel_multiplier(adjusted_mode);
int rate; int rate;
int need_aux = IS_MRST(dev) ? 1 : 0;
if (!mode) if (!mode)
return; return;
...@@ -1060,7 +1063,11 @@ static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder, ...@@ -1060,7 +1063,11 @@ static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
return; return;
/* Set the SDVO control regs. */ /* Set the SDVO control regs. */
if (need_aux)
sdvox = REG_READ_AUX(psb_intel_sdvo->sdvo_reg);
else
sdvox = REG_READ(psb_intel_sdvo->sdvo_reg); sdvox = REG_READ(psb_intel_sdvo->sdvo_reg);
switch (psb_intel_sdvo->sdvo_reg) { switch (psb_intel_sdvo->sdvo_reg) {
case SDVOB: case SDVOB:
sdvox &= SDVOB_PRESERVE_MASK; sdvox &= SDVOB_PRESERVE_MASK;
...@@ -1090,6 +1097,8 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode) ...@@ -1090,6 +1097,8 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder);
u32 temp; u32 temp;
int i;
int need_aux = IS_MRST(dev) ? 1 : 0;
switch (mode) { switch (mode) {
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
...@@ -1108,19 +1117,27 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode) ...@@ -1108,19 +1117,27 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode); psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode);
if (mode == DRM_MODE_DPMS_OFF) { if (mode == DRM_MODE_DPMS_OFF) {
if (need_aux)
temp = REG_READ_AUX(psb_intel_sdvo->sdvo_reg);
else
temp = REG_READ(psb_intel_sdvo->sdvo_reg); temp = REG_READ(psb_intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) != 0) { if ((temp & SDVO_ENABLE) != 0) {
psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp & ~SDVO_ENABLE); psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp & ~SDVO_ENABLE);
} }
} }
} else { } else {
bool input1, input2; bool input1, input2;
int i;
u8 status; u8 status;
if (need_aux)
temp = REG_READ_AUX(psb_intel_sdvo->sdvo_reg);
else
temp = REG_READ(psb_intel_sdvo->sdvo_reg); temp = REG_READ(psb_intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) == 0) if ((temp & SDVO_ENABLE) == 0)
psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp | SDVO_ENABLE); psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp | SDVO_ENABLE);
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
gma_wait_for_vblank(dev); gma_wait_for_vblank(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment