From 4d57326d0ba20fbd7d4ed20454e4cb34c2bdd1b2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Apr 2010 15:32:42 -0400 Subject: [PATCH] drm/radeon/kms: reserve vbios scratch vram v2 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen.c | 6 ++++ drivers/gpu/drm/radeon/r300.c | 6 ++++ drivers/gpu/drm/radeon/r520.c | 6 ++++ drivers/gpu/drm/radeon/r600.c | 6 ++++ drivers/gpu/drm/radeon/radeon.h | 5 ++- drivers/gpu/drm/radeon/radeon_atombios.c | 49 ++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_device.c | 1 + drivers/gpu/drm/radeon/rs600.c | 6 ++++ drivers/gpu/drm/radeon/rs690.c | 6 ++++ drivers/gpu/drm/radeon/rv515.c | 6 ++++ drivers/gpu/drm/radeon/rv770.c | 6 ++++ 11 files changed, 102 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index acae0ea..a1d3907 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1264,6 +1264,12 @@ int evergreen_mc_init(struct radeon_device *rdev) /* size in MB on evergreen */ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; + /* XXX deal with vbios scratch not at the end of vram */ + if (rdev->mc.bios_scratch_offset && + (rdev->mc.bios_scratch_offset <= rdev->mc.real_vram_size)) { + rdev->mc.mc_vram_size = rdev->mc.bios_scratch_offset; + rdev->mc.real_vram_size = rdev->mc.bios_scratch_offset; + } rdev->mc.visible_vram_size = rdev->mc.aper_size; r600_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 199110e..a139901 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -488,6 +488,12 @@ void r300_mc_init(struct radeon_device *rdev) base = rdev->mc.aper_base; if (rdev->flags & RADEON_IS_IGP) base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; + /* XXX deal with vbios scratch not at the end of vram */ + if (rdev->mc.bios_scratch_offset && + (rdev->mc.bios_scratch_offset <= rdev->mc.real_vram_size)) { + rdev->mc.mc_vram_size = rdev->mc.bios_scratch_offset; + rdev->mc.real_vram_size = rdev->mc.bios_scratch_offset; + } radeon_vram_location(rdev, &rdev->mc, base); if (!(rdev->flags & RADEON_IS_AGP)) radeon_gtt_location(rdev, &rdev->mc); diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 870111e..5eeaf4e 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -124,6 +124,12 @@ void r520_mc_init(struct radeon_device *rdev) r520_vram_get_type(rdev); r100_vram_init_sizes(rdev); + /* XXX deal with vbios scratch not at the end of vram */ + if (rdev->mc.bios_scratch_offset && + (rdev->mc.bios_scratch_offset <= rdev->mc.real_vram_size)) { + rdev->mc.mc_vram_size = rdev->mc.bios_scratch_offset; + rdev->mc.real_vram_size = rdev->mc.bios_scratch_offset; + } radeon_vram_location(rdev, &rdev->mc, 0); if (!(rdev->flags & RADEON_IS_AGP)) radeon_gtt_location(rdev, &rdev->mc); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 7b4c5a7..0677f6d 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -728,6 +728,12 @@ int r600_mc_init(struct radeon_device *rdev) /* Setup GPU memory space */ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); + /* XXX deal with vbios scratch not at the end of vram */ + if (rdev->mc.bios_scratch_offset && + (rdev->mc.bios_scratch_offset <= rdev->mc.real_vram_size)) { + rdev->mc.mc_vram_size = rdev->mc.bios_scratch_offset; + rdev->mc.real_vram_size = rdev->mc.bios_scratch_offset; + } rdev->mc.visible_vram_size = rdev->mc.aper_size; r600_vram_gtt_location(rdev, &rdev->mc); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e912098..f0bb06b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -347,6 +347,9 @@ struct radeon_mc { int vram_mtrr; bool vram_is_ddr; bool igp_sideport_enabled; + /* vbios reserved area in bytes */ + u64 bios_scratch_offset; + u64 bios_scratch_size; }; bool radeon_combios_sideport_present(struct radeon_device *rdev); @@ -1150,7 +1153,7 @@ int radeon_combios_init(struct radeon_device *rdev); void radeon_combios_fini(struct radeon_device *rdev); int radeon_atombios_init(struct radeon_device *rdev); void radeon_atombios_fini(struct radeon_device *rdev); - +void radeon_atom_get_bios_vram_scratch_info(struct radeon_device *rdev); /* * RING helpers. diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 2730199..296696a 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2330,3 +2330,52 @@ radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on) else WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch); } + +union firmware_vram_usage { + ATOM_VRAM_USAGE_BY_FIRMWARE info; + ATOM_VRAM_USAGE_BY_FIRMWARE_V1_5 info_15; +}; + +void radeon_atom_get_bios_vram_scratch_info(struct radeon_device *rdev) +{ + struct atom_context *ctx = rdev->mode_info.atom_context; + int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware); + uint16_t data_offset; + u64 usage_size = 0; + u64 usage_offset = 0; + u8 frev, crev; + union firmware_vram_usage *usage; + + if (atom_parse_data_header(ctx, index, NULL, &frev, &crev, &data_offset)) { + usage = (union firmware_vram_usage *)(ctx->bios + data_offset); + + switch (crev) { + case 1: + case 2: + case 4: + usage_size = + usage->info.asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; + usage_offset = + usage->info.asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware; + /* from RV770 StartAddr is KB aligned */ + if (rdev->family >= CHIP_RV770) + usage_offset *= 1024; + break; + case 5: + usage_size = + usage->info_15.asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; + usage_offset = + usage->info_15.asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware; + /* from RV770 StartAddr is KB aligned */ + if (rdev->family >= CHIP_RV770) + usage_offset *= 1024; + break; + default: + DRM_ERROR("Unsupported VRAM Usage table: %d %d\n", frev, crev); + break; + } + } + + rdev->mc.bios_scratch_offset = usage_offset; + rdev->mc.bios_scratch_size = usage_size; +} diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index c34f682..7f1beb7 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -386,6 +386,7 @@ int radeon_atombios_init(struct radeon_device *rdev) rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); mutex_init(&rdev->mode_info.atom_context->mutex); radeon_atom_initialize_bios_scratch_regs(rdev->ddev); + radeon_atom_get_bios_vram_scratch_info(rdev); atom_allocate_fb_scratch(rdev->mode_info.atom_context); return 0; } diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index a16d9d7..1ef92fe 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -542,6 +542,12 @@ void rs600_mc_init(struct radeon_device *rdev) rdev->mc.vram_width = 128; rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); rdev->mc.mc_vram_size = rdev->mc.real_vram_size; + /* XXX deal with vbios scratch not at the end of vram */ + if (rdev->mc.bios_scratch_offset && + (rdev->mc.bios_scratch_offset <= rdev->mc.real_vram_size)) { + rdev->mc.mc_vram_size = rdev->mc.bios_scratch_offset; + rdev->mc.real_vram_size = rdev->mc.bios_scratch_offset; + } rdev->mc.visible_vram_size = rdev->mc.aper_size; rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); base = RREG32_MC(R_000004_MC_FB_LOCATION); diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 56a0aec..e2c345a 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -151,6 +151,12 @@ void rs690_mc_init(struct radeon_device *rdev) rdev->mc.vram_width = 128; rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); rdev->mc.mc_vram_size = rdev->mc.real_vram_size; + /* XXX deal with vbios scratch not at the end of vram */ + if (rdev->mc.bios_scratch_offset && + (rdev->mc.bios_scratch_offset <= rdev->mc.real_vram_size)) { + rdev->mc.mc_vram_size = rdev->mc.bios_scratch_offset; + rdev->mc.real_vram_size = rdev->mc.bios_scratch_offset; + } rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); rdev->mc.visible_vram_size = rdev->mc.aper_size; diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index b42f8d9..82a09e3 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -193,6 +193,12 @@ void rv515_mc_init(struct radeon_device *rdev) rv515_vram_get_type(rdev); r100_vram_init_sizes(rdev); + /* XXX deal with vbios scratch not at the end of vram */ + if (rdev->mc.bios_scratch_offset && + (rdev->mc.bios_scratch_offset <= rdev->mc.real_vram_size)) { + rdev->mc.mc_vram_size = rdev->mc.bios_scratch_offset; + rdev->mc.real_vram_size = rdev->mc.bios_scratch_offset; + } radeon_vram_location(rdev, &rdev->mc, 0); if (!(rdev->flags & RADEON_IS_AGP)) radeon_gtt_location(rdev, &rdev->mc); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 75e9067..c1951e8 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -908,6 +908,12 @@ int rv770_mc_init(struct radeon_device *rdev) /* Setup GPU memory space */ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); + /* XXX deal with vbios scratch not at the end of vram */ + if (rdev->mc.bios_scratch_offset && + (rdev->mc.bios_scratch_offset <= rdev->mc.real_vram_size)) { + rdev->mc.mc_vram_size = rdev->mc.bios_scratch_offset; + rdev->mc.real_vram_size = rdev->mc.bios_scratch_offset; + } rdev->mc.visible_vram_size = rdev->mc.aper_size; r600_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); -- 1.5.6.3