Merge branch 'drm-fixes-3.10' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

Alex writes:
Just a few fixes for radeon.  The big one is a fix for hangs on older
asics due to the ordering of interrupt initialization.

* 'drm-fixes-3.10' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: don't allow audio on DCE6
  drm/radeon: Use direct mapping for fast fb access on RS780/RS880 (v2)
  radeon: Fix system hang issue when using KMS with older cards
This commit is contained in:
Dave Airlie 2013-06-05 14:33:26 +10:00
commit ec7fdeee19
17 changed files with 143 additions and 48 deletions

View file

@ -667,6 +667,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
int
atombios_get_encoder_mode(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_connector *connector;
struct radeon_connector *radeon_connector;
@ -693,7 +695,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
radeon_audio)
radeon_audio &&
!ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */
return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital)
return ATOM_ENCODER_MODE_DVI;
@ -704,7 +707,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
case DRM_MODE_CONNECTOR_HDMIA:
default:
if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
radeon_audio)
radeon_audio &&
!ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */
return ATOM_ENCODER_MODE_HDMI;
else
return ATOM_ENCODER_MODE_DVI;
@ -718,7 +722,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
return ATOM_ENCODER_MODE_DP;
else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
radeon_audio)
radeon_audio &&
!ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */
return ATOM_ENCODER_MODE_HDMI;
else
return ATOM_ENCODER_MODE_DVI;

View file

@ -4754,6 +4754,12 @@ static int evergreen_startup(struct radeon_device *rdev)
rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
r = r600_irq_init(rdev);
if (r) {
DRM_ERROR("radeon: IH init failed (%d).\n", r);
@ -4923,10 +4929,6 @@ int evergreen_init(struct radeon_device *rdev)
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);

View file

@ -2025,6 +2025,12 @@ static int cayman_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
r = r600_irq_init(rdev);
if (r) {
DRM_ERROR("radeon: IH init failed (%d).\n", r);
@ -2190,10 +2196,6 @@ int cayman_init(struct radeon_device *rdev)
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
ring->ring_obj = NULL;
r600_ring_init(rdev, ring, 1024 * 1024);

View file

@ -3869,6 +3869,12 @@ static int r100_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
r100_irq_set(rdev);
rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
/* 1M ring buffer */
@ -4022,9 +4028,6 @@ int r100_init(struct radeon_device *rdev)
r100_mc_init(rdev);
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
/* Memory manager */

View file

@ -1382,6 +1382,12 @@ static int r300_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
r100_irq_set(rdev);
rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
/* 1M ring buffer */
@ -1514,9 +1520,6 @@ int r300_init(struct radeon_device *rdev)
r300_mc_init(rdev);
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
/* Memory manager */

View file

@ -265,6 +265,12 @@ static int r420_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
r100_irq_set(rdev);
rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
/* 1M ring buffer */
@ -411,10 +417,6 @@ int r420_init(struct radeon_device *rdev)
if (r) {
return r;
}
r = radeon_irq_kms_init(rdev);
if (r) {
return r;
}
/* Memory manager */
r = radeon_bo_init(rdev);
if (r) {

View file

@ -194,6 +194,12 @@ static int r520_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
rs600_irq_set(rdev);
rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
/* 1M ring buffer */
@ -295,9 +301,6 @@ int r520_init(struct radeon_device *rdev)
rv515_debugfs(rdev);
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
/* Memory manager */

View file

@ -1046,6 +1046,24 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev)
return -1;
}
uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg)
{
uint32_t r;
WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg));
r = RREG32(R_0028FC_MC_DATA);
WREG32(R_0028F8_MC_INDEX, ~C_0028F8_MC_IND_ADDR);
return r;
}
void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{
WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg) |
S_0028F8_MC_IND_WR_EN(1));
WREG32(R_0028FC_MC_DATA, v);
WREG32(R_0028F8_MC_INDEX, 0x7F);
}
static void r600_mc_program(struct radeon_device *rdev)
{
struct rv515_mc_save save;
@ -1181,6 +1199,8 @@ static int r600_mc_init(struct radeon_device *rdev)
{
u32 tmp;
int chansize, numchan;
uint32_t h_addr, l_addr;
unsigned long long k8_addr;
/* Get VRAM informations */
rdev->mc.vram_is_ddr = true;
@ -1221,7 +1241,30 @@ static int r600_mc_init(struct radeon_device *rdev)
if (rdev->flags & RADEON_IS_IGP) {
rs690_pm_info(rdev);
rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
/* Use K8 direct mapping for fast fb access. */
rdev->fastfb_working = false;
h_addr = G_000012_K8_ADDR_EXT(RREG32_MC(R_000012_MC_MISC_UMA_CNTL));
l_addr = RREG32_MC(R_000011_K8_FB_LOCATION);
k8_addr = ((unsigned long long)h_addr) << 32 | l_addr;
#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
if (k8_addr + rdev->mc.visible_vram_size < 0x100000000ULL)
#endif
{
/* FastFB shall be used with UMA memory. Here it is simply disabled when sideport
* memory is present.
*/
if (rdev->mc.igp_sideport_enabled == false && radeon_fastfb == 1) {
DRM_INFO("Direct mapping: aper base at 0x%llx, replaced by direct mapping base 0x%llx.\n",
(unsigned long long)rdev->mc.aper_base, k8_addr);
rdev->mc.aper_base = (resource_size_t)k8_addr;
rdev->fastfb_working = true;
}
}
}
}
radeon_update_bandwidth_info(rdev);
return 0;
}
@ -3202,6 +3245,12 @@ static int r600_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
r = r600_irq_init(rdev);
if (r) {
DRM_ERROR("radeon: IH init failed (%d).\n", r);
@ -3356,10 +3405,6 @@ int r600_init(struct radeon_device *rdev)
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);

View file

@ -1342,6 +1342,14 @@
#define PACKET3_STRMOUT_BASE_UPDATE 0x72 /* r7xx */
#define PACKET3_SURFACE_BASE_UPDATE 0x73
#define R_000011_K8_FB_LOCATION 0x11
#define R_000012_MC_MISC_UMA_CNTL 0x12
#define G_000012_K8_ADDR_EXT(x) (((x) >> 0) & 0xFF)
#define R_0028F8_MC_INDEX 0x28F8
#define S_0028F8_MC_IND_ADDR(x) (((x) & 0x1FF) << 0)
#define C_0028F8_MC_IND_ADDR 0xFFFFFE00
#define S_0028F8_MC_IND_WR_EN(x) (((x) & 0x1) << 9)
#define R_0028FC_MC_DATA 0x28FC
#define R_008020_GRBM_SOFT_RESET 0x8020
#define S_008020_SOFT_RESET_CP(x) (((x) & 1) << 0)

View file

@ -122,6 +122,10 @@ static void radeon_register_accessor_init(struct radeon_device *rdev)
rdev->mc_rreg = &rs600_mc_rreg;
rdev->mc_wreg = &rs600_mc_wreg;
}
if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
rdev->mc_rreg = &rs780_mc_rreg;
rdev->mc_wreg = &rs780_mc_wreg;
}
if (rdev->family >= CHIP_R600) {
rdev->pciep_rreg = &r600_pciep_rreg;
rdev->pciep_wreg = &r600_pciep_wreg;

View file

@ -347,6 +347,8 @@ extern bool r600_gui_idle(struct radeon_device *rdev);
extern void r600_pm_misc(struct radeon_device *rdev);
extern void r600_pm_init_profile(struct radeon_device *rdev);
extern void rs780_pm_init_profile(struct radeon_device *rdev);
extern uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg);
extern void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
extern void r600_pm_get_dynpm_state(struct radeon_device *rdev);
extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes);
extern int r600_get_pcie_lanes(struct radeon_device *rdev);

View file

@ -417,6 +417,12 @@ static int rs400_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
r100_irq_set(rdev);
rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
/* 1M ring buffer */
@ -533,9 +539,6 @@ int rs400_init(struct radeon_device *rdev)
rs400_mc_init(rdev);
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
/* Memory manager */

View file

@ -923,6 +923,12 @@ static int rs600_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
rs600_irq_set(rdev);
rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
/* 1M ring buffer */
@ -1045,9 +1051,6 @@ int rs600_init(struct radeon_device *rdev)
rs600_debugfs(rdev);
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
/* Memory manager */

View file

@ -651,6 +651,12 @@ static int rs690_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
rs600_irq_set(rdev);
rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
/* 1M ring buffer */
@ -774,9 +780,6 @@ int rs690_init(struct radeon_device *rdev)
rv515_debugfs(rdev);
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
/* Memory manager */

View file

@ -532,6 +532,12 @@ static int rv515_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
rs600_irq_set(rdev);
rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
/* 1M ring buffer */
@ -660,9 +666,6 @@ int rv515_init(struct radeon_device *rdev)
rv515_debugfs(rdev);
/* Fence driver */
r = radeon_fence_driver_init(rdev);
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
/* Memory manager */

View file

@ -1887,6 +1887,12 @@ static int rv770_startup(struct radeon_device *rdev)
rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
r = r600_irq_init(rdev);
if (r) {
DRM_ERROR("radeon: IH init failed (%d).\n", r);
@ -2045,10 +2051,6 @@ int rv770_init(struct radeon_device *rdev)
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);

View file

@ -5350,6 +5350,12 @@ static int si_startup(struct radeon_device *rdev)
}
/* Enable IRQ */
if (!rdev->irq.installed) {
r = radeon_irq_kms_init(rdev);
if (r)
return r;
}
r = si_irq_init(rdev);
if (r) {
DRM_ERROR("radeon: IH init failed (%d).\n", r);
@ -5533,10 +5539,6 @@ int si_init(struct radeon_device *rdev)
if (r)
return r;
r = radeon_irq_kms_init(rdev);
if (r)
return r;
ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
ring->ring_obj = NULL;
r600_ring_init(rdev, ring, 1024 * 1024);