summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/radeon_atombios.c52
-rw-r--r--linux-core/radeon_combios.c41
-rw-r--r--linux-core/radeon_connectors.c3
-rw-r--r--linux-core/radeon_display.c1
-rw-r--r--linux-core/radeon_encoders.c200
-rw-r--r--linux-core/radeon_gem.c2
-rw-r--r--linux-core/radeon_legacy_encoders.c110
-rw-r--r--linux-core/radeon_mode.h5
-rw-r--r--shared-core/radeon_cp.c6
9 files changed, 398 insertions, 22 deletions
diff --git a/linux-core/radeon_atombios.c b/linux-core/radeon_atombios.c
index eb482d92..ca287bca 100644
--- a/linux-core/radeon_atombios.c
+++ b/linux-core/radeon_atombios.c
@@ -363,3 +363,55 @@ void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable)
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
+void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t bios_2_scratch, bios_6_scratch;
+
+ if (dev_priv->chip_family >= CHIP_R600) {
+ bios_2_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH);
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+ } else {
+ bios_2_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH);
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+ }
+
+ /* let the bios control the backlight */
+ bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
+
+ /* tell the bios not to handle mode switching */
+ bios_6_scratch |= (ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH |
+ ATOM_S6_ACC_MODE);
+
+ if (dev_priv->chip_family >= CHIP_R600) {
+ RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch);
+ RADEON_WRITE(R600_BIOS_6_SCRATCH, bios_6_scratch);
+ } else {
+ RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
+ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
+ }
+
+}
+
+void
+radeon_atom_output_lock(struct drm_encoder *encoder, bool lock)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t bios_6_scratch;
+
+ if (dev_priv->chip_family >= CHIP_R600)
+ bios_6_scratch = RADEON_READ(R600_BIOS_6_SCRATCH);
+ else
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+
+ if (lock)
+ bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
+ else
+ bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
+
+ if (dev_priv->chip_family >= CHIP_R600)
+ RADEON_WRITE(R600_BIOS_6_SCRATCH, bios_6_scratch);
+ else
+ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
+}
diff --git a/linux-core/radeon_combios.c b/linux-core/radeon_combios.c
index 02f7335f..200761ee 100644
--- a/linux-core/radeon_combios.c
+++ b/linux-core/radeon_combios.c
@@ -1301,3 +1301,44 @@ void radeon_combios_asic_init(struct drm_device *dev)
combios_parse_mmio_table(dev, table);
}
+
+void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t bios_0_scratch, bios_6_scratch, bios_7_scratch;
+
+ bios_0_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH);
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+ //bios_7_scratch = RADEON_READ(RADEON_BIOS_7_SCRATCH);
+
+ /* let the bios control the backlight */
+ bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN;
+
+ /* tell the bios not to handle mode switching */
+ bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS |
+ RADEON_ACC_MODE_CHANGE);
+
+ /* tell the bios a driver is loaded */
+ //bios_7_scratch |= RADEON_DRV_LOADED;
+
+ RADEON_WRITE(RADEON_BIOS_0_SCRATCH, bios_0_scratch);
+ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
+ //RADEON_WRITE(RADEON_BIOS_7_SCRATCH, bios_7_scratch);
+}
+
+void
+radeon_combios_output_lock(struct drm_encoder *encoder, bool lock)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ uint32_t bios_6_scratch;
+
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+
+ if (lock)
+ bios_6_scratch |= RADEON_DRIVER_CRITICAL;
+ else
+ bios_6_scratch &= ~RADEON_DRIVER_CRITICAL;
+
+ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
+}
diff --git a/linux-core/radeon_connectors.c b/linux-core/radeon_connectors.c
index 32f969ab..7b2d7c4d 100644
--- a/linux-core/radeon_connectors.c
+++ b/linux-core/radeon_connectors.c
@@ -66,6 +66,7 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector,
static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
{
+ // check acpi lid status ???
return connector_status_connected;
}
@@ -240,7 +241,7 @@ struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
}
/* see if we have a default encoder TODO */
-
+
/* then check use digitial */
/* pick the first one */
if (enc_id) {
diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c
index 39eb91eb..2877cd3b 100644
--- a/linux-core/radeon_display.c
+++ b/linux-core/radeon_display.c
@@ -600,4 +600,3 @@ void radeon_modeset_cleanup(struct drm_device *dev)
{
drm_mode_config_cleanup(dev);
}
-
diff --git a/linux-core/radeon_encoders.c b/linux-core/radeon_encoders.c
index 04c57092..ec36e43d 100644
--- a/linux-core/radeon_encoders.c
+++ b/linux-core/radeon_encoders.c
@@ -134,7 +134,6 @@ static void atombios_display_device_control(struct drm_encoder *encoder, int ind
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
-
static void atombios_scaler_setup(struct drm_encoder *encoder, struct drm_display_mode *mode)
{
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
@@ -213,7 +212,7 @@ void atombios_set_crtc_source(struct drm_encoder *encoder, int source)
default:
return;
}
-
+
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)param);
}
@@ -264,7 +263,7 @@ static void radeon_lvtma_mode_set(struct drm_encoder *encoder,
else
args.ucMisc = 0;
args.usPixelClock = cpu_to_le16(adjusted_mode->clock / 10);
-
+
printk("executing set LVDS encoder\n");
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
@@ -273,18 +272,44 @@ static void radeon_lvtma_mode_set(struct drm_encoder *encoder,
static void radeon_lvtma_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
int index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
+ uint32_t bios_2_scratch, bios_3_scratch;
+
+ if (dev_priv->chip_family >= CHIP_R600) {
+ bios_2_scratch = RADEON_READ(R600_BIOS_2_SCRATCH);
+ bios_3_scratch = RADEON_READ(R600_BIOS_3_SCRATCH);
+ } else {
+ bios_2_scratch = RADEON_READ(RADEON_BIOS_2_SCRATCH);
+ bios_3_scratch = RADEON_READ(RADEON_BIOS_3_SCRATCH);
+ }
+
+ bios_2_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
+ bios_3_scratch |= (radeon_crtc->crtc_id << 17);
switch(mode) {
case DRM_MODE_DPMS_ON:
atombios_display_device_control(encoder, index, ATOM_ENABLE);
+ bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE;
+ bios_3_scratch |= ATOM_S3_LCD1_ACTIVE;
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
atombios_display_device_control(encoder, index, ATOM_DISABLE);
+ bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE;
+ bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE;
break;
}
+
+ if (dev_priv->chip_family >= CHIP_R600) {
+ RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch);
+ RADEON_WRITE(R600_BIOS_3_SCRATCH, bios_3_scratch);
+ } else {
+ RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
+ RADEON_WRITE(RADEON_BIOS_3_SCRATCH, bios_3_scratch);
+ }
}
static bool radeon_lvtma_mode_fixup(struct drm_encoder *encoder,
@@ -297,18 +322,20 @@ static bool radeon_lvtma_mode_fixup(struct drm_encoder *encoder,
if (radeon_encoder->rmx_type != RMX_OFF)
radeon_rmx_mode_fixup(encoder, mode, adjusted_mode);
-
+
return true;
}
static void radeon_lvtma_prepare(struct drm_encoder *encoder)
{
+ radeon_atom_output_lock(encoder, true);
radeon_lvtma_dpms(encoder, DRM_MODE_DPMS_OFF);
}
static void radeon_lvtma_commit(struct drm_encoder *encoder)
{
radeon_lvtma_dpms(encoder, DRM_MODE_DPMS_ON);
+ radeon_atom_output_lock(encoder, false);
}
static const struct drm_encoder_helper_funcs radeon_atom_lvtma_helper_funcs = {
@@ -366,25 +393,91 @@ static void radeon_atom_dac_dpms(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev;
struct drm_radeon_private *dev_priv = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
int atom_type = -1;
int index;
+ uint32_t bios_2_scratch, bios_3_scratch;
atom_type = atom_dac_find_atom_type(radeon_encoder, NULL);
if (atom_type == -1)
return;
-
+
+ if (dev_priv->chip_family >= CHIP_R600) {
+ bios_2_scratch = RADEON_READ(R600_BIOS_2_SCRATCH);
+ bios_3_scratch = RADEON_READ(R600_BIOS_3_SCRATCH);
+ } else {
+ bios_2_scratch = RADEON_READ(RADEON_BIOS_2_SCRATCH);
+ bios_3_scratch = RADEON_READ(RADEON_BIOS_3_SCRATCH);
+ }
+
switch(atom_type) {
case ATOM_DEVICE_CRT1_INDEX:
index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
+ bios_2_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
+ bios_3_scratch |= (radeon_crtc->crtc_id << 16);
+ switch(mode) {
+ case DRM_MODE_DPMS_ON:
+ bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE;
+ bios_3_scratch |= ATOM_S3_CRT1_ACTIVE;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE;
+ bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE;
+ break;
+ }
break;
case ATOM_DEVICE_CRT2_INDEX:
index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
+ bios_2_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
+ bios_3_scratch |= (radeon_crtc->crtc_id << 20);
+ switch(mode) {
+ case DRM_MODE_DPMS_ON:
+ bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE;
+ bios_3_scratch |= ATOM_S3_CRT2_ACTIVE;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE;
+ bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE;
+ break;
+ }
break;
case ATOM_DEVICE_TV1_INDEX:
index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+ bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
+ bios_3_scratch |= (radeon_crtc->crtc_id << 18);
+ switch(mode) {
+ case DRM_MODE_DPMS_ON:
+ bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE;
+ bios_3_scratch |= ATOM_S3_TV1_ACTIVE;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE;
+ bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE;
+ break;
+ }
break;
case ATOM_DEVICE_CV_INDEX:
index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+ bios_2_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;
+ bios_3_scratch |= (radeon_crtc->crtc_id << 24);
+ switch(mode) {
+ case DRM_MODE_DPMS_ON:
+ bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE;
+ bios_3_scratch |= ATOM_S3_CV_ACTIVE;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ bios_2_scratch |= ATOM_S2_CV_DPMS_STATE;
+ bios_3_scratch &= ~ATOM_S3_CV_ACTIVE;
+ break;
+ }
break;
default:
return;
@@ -394,12 +487,20 @@ static void radeon_atom_dac_dpms(struct drm_encoder *encoder, int mode)
case DRM_MODE_DPMS_ON:
atombios_display_device_control(encoder, index, ATOM_ENABLE);
break;
- case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
atombios_display_device_control(encoder, index, ATOM_DISABLE);
break;
}
+
+ if (dev_priv->chip_family >= CHIP_R600) {
+ RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch);
+ RADEON_WRITE(R600_BIOS_3_SCRATCH, bios_3_scratch);
+ } else {
+ RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
+ RADEON_WRITE(RADEON_BIOS_3_SCRATCH, bios_3_scratch);
+ }
}
static bool radeon_atom_dac_mode_fixup(struct drm_encoder *encoder,
@@ -411,12 +512,14 @@ static bool radeon_atom_dac_mode_fixup(struct drm_encoder *encoder,
static void radeon_atom_dac_prepare(struct drm_encoder *encoder)
{
+ radeon_atom_output_lock(encoder, true);
radeon_atom_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
}
static void radeon_atom_dac_commit(struct drm_encoder *encoder)
{
radeon_atom_dac_dpms(encoder, DRM_MODE_DPMS_ON);
+ radeon_atom_output_lock(encoder, false);
}
static int atombios_dac_setup(struct drm_encoder *encoder,
@@ -447,7 +550,7 @@ static int atombios_dac_setup(struct drm_encoder *encoder,
args.ucDacStandard = id ? ATOM_DAC2_NTSC : ATOM_DAC1_NTSC;
/* TODO PAL */
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
-
+
return 0;
}
@@ -471,7 +574,7 @@ static int atombios_tv1_setup(struct drm_encoder *encoder,
}
args.sTVEncoder.usPixelClock = cpu_to_le16(mode->clock / 10);
-
+
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
return 0;
}
@@ -496,7 +599,7 @@ static void radeon_atom_dac_mode_set(struct drm_encoder *encoder,
if ((atom_type == ATOM_DEVICE_TV1_INDEX) ||
(atom_type == ATOM_DEVICE_CV_INDEX))
atombios_tv1_setup(encoder, adjusted_mode, atom_type);
-
+
}
static bool atom_dac_load_detect(struct drm_encoder *encoder, int atom_devices)
@@ -525,11 +628,11 @@ static bool atom_dac_load_detect(struct drm_encoder *encoder, int atom_devices)
args.sDacload.ucMisc = 1;
} else
return false;
-
+
DRM_DEBUG("writing %x %x\n", args.sDacload.usDeviceID, args.sDacload.ucDacType);
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
return true;
-}
+}
static enum drm_connector_status radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
{
@@ -551,7 +654,7 @@ static enum drm_connector_status radeon_atom_dac_detect(struct drm_encoder *enco
}
- if (dev_priv->chip_family >= CHIP_R600)
+ if (dev_priv->chip_family >= CHIP_R600)
bios_0_scratch = RADEON_READ(R600_BIOS_0_SCRATCH);
else
bios_0_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH);
@@ -607,7 +710,7 @@ static void atombios_tmds1_setup(struct drm_encoder *encoder,
args.usPixelClock = cpu_to_le16(mode->clock / 10);
- atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
+ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
static void atombios_tmds2_setup(struct drm_encoder *encoder,
@@ -628,7 +731,7 @@ static void atombios_tmds2_setup(struct drm_encoder *encoder,
args.usPixelClock = cpu_to_le16(mode->clock / 10);
- atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
+ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
@@ -652,7 +755,7 @@ static void atombios_ext_tmds_setup(struct drm_encoder *encoder,
// TODO 6-bit DAC
// args.usPixelClock = cpu_to_le16(mode->clock / 10);
- atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
+ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
static void atombios_dig1_setup(struct drm_encoder *encoder,
@@ -680,7 +783,7 @@ static void atombios_dig1_setup(struct drm_encoder *encoder,
}
// TODO Encoder MODE
- atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
+ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
static void atombios_ddia_setup(struct drm_encoder *encoder,
@@ -699,7 +802,7 @@ static void atombios_ddia_setup(struct drm_encoder *encoder,
else
args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = 0;
- atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
+ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
struct drm_encoder *radeon_encoder_atom_dac_add(struct drm_device *dev, int bios_index, int dac_type, int with_tv)
@@ -760,8 +863,10 @@ static void radeon_atom_tmds_dpms(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev;
struct drm_radeon_private *dev_priv = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
int atom_type = -1;
int index = -1;
+ uint32_t bios_2_scratch, bios_3_scratch;
if (radeon_encoder->atom_device & ATOM_DEVICE_DFP1_SUPPORT)
atom_type = ATOM_DEVICE_DFP1_INDEX;
@@ -773,15 +878,65 @@ static void radeon_atom_tmds_dpms(struct drm_encoder *encoder, int mode)
if (atom_type == -1)
return;
+ if (dev_priv->chip_family >= CHIP_R600) {
+ bios_2_scratch = RADEON_READ(R600_BIOS_2_SCRATCH);
+ bios_3_scratch = RADEON_READ(R600_BIOS_3_SCRATCH);
+ } else {
+ bios_2_scratch = RADEON_READ(RADEON_BIOS_2_SCRATCH);
+ bios_3_scratch = RADEON_READ(RADEON_BIOS_3_SCRATCH);
+ }
+
switch(atom_type) {
case ATOM_DEVICE_DFP1_INDEX:
index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
+ bios_2_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
+ bios_3_scratch |= (radeon_crtc->crtc_id << 19);
+ switch(mode) {
+ case DRM_MODE_DPMS_ON:
+ bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE;
+ bios_3_scratch |= ATOM_S3_DFP1_ACTIVE;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE;
+ bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE;
+ break;
+ }
break;
case ATOM_DEVICE_DFP2_INDEX:
index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+ bios_2_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
+ bios_3_scratch |= (radeon_crtc->crtc_id << 23);
+ switch(mode) {
+ case DRM_MODE_DPMS_ON:
+ bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE;
+ bios_3_scratch |= ATOM_S3_DFP2_ACTIVE;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE;
+ bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE;
+ break;
+ }
break;
case ATOM_DEVICE_DFP3_INDEX:
index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
+ bios_2_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
+ bios_3_scratch |= (radeon_crtc->crtc_id << 25);
+ switch(mode) {
+ case DRM_MODE_DPMS_ON:
+ bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE;
+ bios_3_scratch |= ATOM_S3_DFP3_ACTIVE;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE;
+ bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE;
+ break;
+ }
break;
}
@@ -798,6 +953,14 @@ static void radeon_atom_tmds_dpms(struct drm_encoder *encoder, int mode)
atombios_display_device_control(encoder, index, ATOM_DISABLE);
break;
}
+
+ if (dev_priv->chip_family >= CHIP_R600) {
+ RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch);
+ RADEON_WRITE(R600_BIOS_3_SCRATCH, bios_3_scratch);
+ } else {
+ RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch);
+ RADEON_WRITE(RADEON_BIOS_3_SCRATCH, bios_3_scratch);
+ }
}
static bool radeon_atom_tmds_mode_fixup(struct drm_encoder *encoder,
@@ -845,12 +1008,14 @@ static void radeon_atom_tmds_mode_set(struct drm_encoder *encoder,
static void radeon_atom_tmds_prepare(struct drm_encoder *encoder)
{
+ radeon_atom_output_lock(encoder, true);
radeon_atom_tmds_dpms(encoder, DRM_MODE_DPMS_OFF);
}
static void radeon_atom_tmds_commit(struct drm_encoder *encoder)
{
radeon_atom_tmds_dpms(encoder, DRM_MODE_DPMS_ON);
+ radeon_atom_output_lock(encoder, false);
}
static const struct drm_encoder_helper_funcs radeon_atom_tmds_helper_funcs = {
@@ -894,4 +1059,3 @@ struct drm_encoder *radeon_encoder_atom_tmds_add(struct drm_device *dev, int bio
radeon_encoder->atom_device &= analog_enc_mask;
return encoder;
}
-
diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c
index 6a7529cd..d572008a 100644
--- a/linux-core/radeon_gem.c
+++ b/linux-core/radeon_gem.c
@@ -225,7 +225,7 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
args->addr_ptr = (uint64_t) addr;
return 0;
-
+
}
int radeon_gem_pin_ioctl(struct drm_device *dev, void *data,
diff --git a/linux-core/radeon_legacy_encoders.c b/linux-core/radeon_legacy_encoders.c
index 48cdd18c..64521547 100644
--- a/linux-core/radeon_legacy_encoders.c
+++ b/linux-core/radeon_legacy_encoders.c
@@ -197,10 +197,19 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev;
struct drm_radeon_private *dev_priv = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man;
+ uint32_t bios_5_scratch, bios_6_scratch;
DRM_DEBUG("\n");
+ // FIXME atom/legacy cards like r4xx
+ bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH);
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+
+ bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK;
+ bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_LCD1_CRTC_SHIFT);
+
switch (mode) {
case DRM_MODE_DPMS_ON:
disp_pwr_man = RADEON_READ(RADEON_DISP_PWR_MAN);
@@ -228,6 +237,11 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
/* enable backlight */
lvds_gen_cntl |= RADEON_LVDS_BLON;
RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
+
+ /* update bios scratch regs */
+ bios_5_scratch |= RADEON_LCD1_ON;
+ bios_6_scratch |= RADEON_LCD_DPMS_ON;
+
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
@@ -239,18 +253,27 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, pixclks_cntl);
+
+ bios_5_scratch &= ~RADEON_LCD1_ON;
+ bios_6_scratch &= ~RADEON_LCD_DPMS_ON;
break;
}
+ RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
+ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
}
static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder)
{
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, true);
radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF);
}
static void radeon_legacy_lvds_commit(struct drm_encoder *encoder)
{
radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON);
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, false);
}
static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
@@ -372,9 +395,20 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode
{
struct drm_device *dev = encoder->dev;
struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
uint32_t crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL);
uint32_t dac_cntl = RADEON_READ(RADEON_DAC_CNTL);
uint32_t dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL);
+ uint32_t bios_5_scratch, bios_6_scratch;
+
+ DRM_DEBUG("\n");
+
+ // FIXME atom/legacy cards like r4xx
+ bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH);
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+
+ bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK;
+ bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT1_CRTC_SHIFT);
DRM_DEBUG("\n");
@@ -385,6 +419,8 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode
dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
RADEON_DAC_PDWN_G |
RADEON_DAC_PDWN_B);
+ bios_5_scratch |= RADEON_CRT1_ON;
+ bios_6_scratch |= RADEON_CRT_DPMS_ON;
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
@@ -394,6 +430,8 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode
dac_macro_cntl |= (RADEON_DAC_PDWN_R |
RADEON_DAC_PDWN_G |
RADEON_DAC_PDWN_B);
+ bios_5_scratch &= ~RADEON_CRT1_ON;
+ bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
break;
}
@@ -401,16 +439,22 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode
RADEON_WRITE(RADEON_DAC_CNTL, dac_cntl);
RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
+ RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
+ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
}
static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder)
{
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, true);
radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
}
static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder)
{
radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_ON);
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, false);
}
static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder,
@@ -527,32 +571,52 @@ static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
uint32_t fp_gen_cntl = RADEON_READ(RADEON_FP_GEN_CNTL);
+ uint32_t bios_5_scratch, bios_6_scratch;
DRM_DEBUG("\n");
+ // FIXME atom/legacy cards like r4xx
+ bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH);
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+
+ bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK;
+ bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP1_CRTC_SHIFT);
+
switch(mode) {
case DRM_MODE_DPMS_ON:
fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+ bios_5_scratch |= RADEON_DFP1_ON;
+ bios_6_scratch |= RADEON_DFP_DPMS_ON;
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+ bios_5_scratch &= ~RADEON_DFP1_ON;
+ bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
break;
}
RADEON_WRITE(RADEON_FP_GEN_CNTL, fp_gen_cntl);
+
+ RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
+ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
}
static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder)
{
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, true);
radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF);
}
static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder)
{
radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_ON);
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, true);
}
static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder,
@@ -691,34 +755,54 @@ static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
uint32_t fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL);
+ uint32_t bios_5_scratch, bios_6_scratch;
DRM_DEBUG("\n");
+ // FIXME atom/legacy cards like r4xx
+ bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH);
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+
+ bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK;
+ bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP2_CRTC_SHIFT);
+
switch(mode) {
case DRM_MODE_DPMS_ON:
fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ bios_5_scratch |= RADEON_DFP2_ON;
+ bios_6_scratch |= RADEON_DFP_DPMS_ON;
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ bios_5_scratch &= ~RADEON_DFP2_ON;
+ bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
break;
}
RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+
+ RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
+ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
}
static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder)
{
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, true);
radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF);
}
static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder)
{
radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_ON);
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, false);
}
static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
@@ -827,11 +911,23 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0;
//uint32_t tv_master_cntl = 0;
+ uint32_t bios_5_scratch, bios_6_scratch;
DRM_DEBUG("\n");
+ // FIXME atom/legacy cards like r4xx
+ bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH);
+ bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH);
+
+ bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK;
+ bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT2_CRTC_SHIFT);
+ // FIXME TV
+ //bios_5_scratch &= ~RADEON_TV1_CRTC_MASK;
+ //bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_TV1_CRTC_SHIFT);
+
if (dev_priv->chip_family == CHIP_R200)
fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL);
else {
@@ -860,6 +956,10 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
RADEON_TV_DAC_BDACPD |
RADEON_TV_DAC_BGSLEEP);
}
+ //bios_5_scratch |= RADEON_TV1_ON;
+ //bios_6_scratch |= RADEON_TV_DPMS_ON;
+ bios_5_scratch |= RADEON_CRT2_ON;
+ bios_6_scratch |= RADEON_CRT_DPMS_ON;
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
@@ -881,6 +981,10 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
RADEON_TV_DAC_BDACPD |
RADEON_TV_DAC_BGSLEEP);
}
+ //bios_5_scratch &= ~RADEON_TV1_ON;
+ //bios_6_scratch &= ~RADEON_TV_DPMS_ON;
+ bios_5_scratch &= ~RADEON_CRT2_ON;
+ bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
break;
}
@@ -892,16 +996,22 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl);
}
+ RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
+ RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
}
static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder)
{
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, true);
radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
}
static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder)
{
radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_ON);
+ // fix me: atom/legacy r4xx
+ radeon_combios_output_lock(encoder, false);
}
static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h
index 7278c42b..d7c60fa6 100644
--- a/linux-core/radeon_mode.h
+++ b/linux-core/radeon_mode.h
@@ -293,6 +293,10 @@ extern bool radeon_combios_get_tmds_info(struct radeon_encoder *encoder);
extern bool radeon_combios_get_tv_info(struct radeon_encoder *encoder);
extern bool radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
extern bool radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder);
+extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock);
+extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev);
+extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock);
+extern void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev);
extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno);
struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev,
@@ -311,6 +315,7 @@ void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_stat
void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable);
void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable);
+void radeon_combios_dyn_clk_setup(struct drm_device *dev, int enable);
void radeon_get_clock_info(struct drm_device *dev);
extern bool radeon_get_atom_connector_info_from_bios_connector_table(struct drm_device *dev);
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index e30696fc..6b71360f 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -2409,8 +2409,12 @@ int radeon_modeset_preinit(struct drm_device *dev)
if (dev_priv->is_atom_bios) {
dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios);
- }
+ radeon_atom_initialize_bios_scratch_regs(dev);
+ } else
+ radeon_combios_initialize_bios_scratch_regs(dev);
+
radeon_get_clock_info(dev);
+
return 0;
}