diff options
-rw-r--r-- | linux-core/radeon_atombios.c | 52 | ||||
-rw-r--r-- | linux-core/radeon_combios.c | 41 | ||||
-rw-r--r-- | linux-core/radeon_connectors.c | 3 | ||||
-rw-r--r-- | linux-core/radeon_display.c | 1 | ||||
-rw-r--r-- | linux-core/radeon_encoders.c | 200 | ||||
-rw-r--r-- | linux-core/radeon_gem.c | 2 | ||||
-rw-r--r-- | linux-core/radeon_legacy_encoders.c | 110 | ||||
-rw-r--r-- | linux-core/radeon_mode.h | 5 | ||||
-rw-r--r-- | shared-core/radeon_cp.c | 6 |
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; } |