Re: [PATCH 1/2] drm/radeon/kms: Fallback to non AGP when acceleration fails to initialize

From: Alex Deucher
Date: Tue Oct 06 2009 - 12:09:54 EST


On Tue, Oct 6, 2009 at 11:27 AM, Jerome Glisse <jglisse@xxxxxxxxxx> wrote:
> When GPU acceleration is not working with AGP try to fallback to non
> AGP GART (either PCI or PCIE GART). This should make KMS failure on
> AGP less painfull. We still need to find out what is wrong when AGP
> fails but at least user have a lot of more chances to get a working
> configuration with acceleration. This patch also cleanup R600/RV770
> fallback path so they use same code as others asics.
>
> Signed-off-by: Jerome Glisse <jglisse@xxxxxxxxxx>
> ---
>  drivers/gpu/drm/radeon/r600.c          |   18 +-----------------
>  drivers/gpu/drm/radeon/radeon_device.c |   25 ++++++++++++++++++++++++-
>  drivers/gpu/drm/radeon/rv770.c         |   18 +-----------------
>  3 files changed, 26 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
> index 9f7eb08..2cef638 100644
> --- a/drivers/gpu/drm/radeon/r600.c
> +++ b/drivers/gpu/drm/radeon/r600.c
> @@ -1560,15 +1560,8 @@ int r600_init(struct radeon_device *rdev)
>        if (r)
>                return r;
>        r = r600_mc_init(rdev);
> -       if (r) {
> -               if (rdev->flags & RADEON_IS_AGP) {
> -                       /* Retry with disabling AGP */
> -                       r600_fini(rdev);
> -                       rdev->flags &= ~RADEON_IS_AGP;
> -                       return r600_init(rdev);
> -               }
> +       if (r)
>                return r;
> -       }
>        /* Memory manager */
>        r = radeon_object_init(rdev);
>        if (r)
> @@ -1597,15 +1590,8 @@ int r600_init(struct radeon_device *rdev)
>
>        r = r600_startup(rdev);
>        if (r) {
> -               if (rdev->flags & RADEON_IS_AGP) {
> -                       /* Retry with disabling AGP */
> -                       r600_fini(rdev);
> -                       rdev->flags &= ~RADEON_IS_AGP;
> -                       return r600_init(rdev);
> -               }
>                r600_suspend(rdev);
>                r600_wb_fini(rdev);
> -               radeon_ib_pool_fini(rdev);
>                radeon_ring_fini(rdev);
>                r600_pcie_gart_fini(rdev);
>                rdev->accel_working = false;
> @@ -1637,10 +1623,8 @@ void r600_fini(struct radeon_device *rdev)
>        radeon_gem_fini(rdev);
>        radeon_fence_driver_fini(rdev);
>        radeon_clocks_fini(rdev);
> -#if __OS_HAS_AGP
>        if (rdev->flags & RADEON_IS_AGP)
>                radeon_agp_fini(rdev);
> -#endif
>        radeon_object_fini(rdev);
>        radeon_atombios_fini(rdev);
>        kfree(rdev->bios);
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
> index 2d07ccc..ec02006 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -565,8 +565,31 @@ int radeon_device_init(struct radeon_device *rdev,
>        DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
>
>        r = radeon_init(rdev);
> -       if (r) {
> +       if (r)
>                return r;
> +       if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
> +               /* Acceleration not working on AGP card try again
> +                * with fallback to PCI or PCIE GART
> +                */
> +               radeon_fini(rdev);
> +               rdev->flags &= ~RADEON_IS_AGP;
> +               if (rdev->family >= CHIP_RV515 ||
> +                       rdev->family == CHIP_RV380 ||
> +                       rdev->family == CHIP_RV410 ||
> +                       rdev->family == CHIP_R423) {
> +                       DRM_INFO("Forcing AGP to PCIE mode\n");
> +                       rdev->flags |= RADEON_IS_PCIE;
> +                       rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
> +                       rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
> +               } else {
> +                       DRM_INFO("Forcing AGP to PCI mode\n");
> +                       rdev->flags |= RADEON_IS_PCI;
> +                       rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
> +                       rdev->asic->gart_set_page = &r100_pci_gart_set_page;
> +               }

The above code is wrong for r6xx/r7xx. should be:
if (rdev->family >= CHIP_R600) {
DRM_INFO("Forcing AGP to PCIE mode\n");
rdev->flags |= RADEON_IS_PCIE;
} else if (rdev->family >= CHIP_RV515 ||
rdev->family == CHIP_RV380 ||
rdev->family == CHIP_RV410 ||
rdev->family == CHIP_R423) {
DRM_INFO("Forcing AGP to PCIE mode\n");
rdev->flags |= RADEON_IS_PCIE;
rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
} else {
DRM_INFO("Forcing AGP to PCI mode\n");
rdev->flags |= RADEON_IS_PCI;
rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
rdev->asic->gart_set_page = &r100_pci_gart_set_page;
}

Otherwise you end up with rv370 pcie gart functions.

> +               r = radeon_init(rdev);
> +               if (r)
> +                       return r;
>        }
>        if (radeon_testing) {
>                radeon_test_moves(rdev);
> diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
> index 295cf14..5c597df 100644
> --- a/drivers/gpu/drm/radeon/rv770.c
> +++ b/drivers/gpu/drm/radeon/rv770.c
> @@ -923,15 +923,8 @@ int rv770_init(struct radeon_device *rdev)
>        if (r)
>                return r;
>        r = rv770_mc_init(rdev);
> -       if (r) {
> -               if (rdev->flags & RADEON_IS_AGP) {
> -                       /* Retry with disabling AGP */
> -                       rv770_fini(rdev);
> -                       rdev->flags &= ~RADEON_IS_AGP;
> -                       return rv770_init(rdev);
> -               }
> +       if (r)
>                return r;
> -       }
>        /* Memory manager */
>        r = radeon_object_init(rdev);
>        if (r)
> @@ -960,15 +953,8 @@ int rv770_init(struct radeon_device *rdev)
>
>        r = rv770_startup(rdev);
>        if (r) {
> -               if (rdev->flags & RADEON_IS_AGP) {
> -                       /* Retry with disabling AGP */
> -                       rv770_fini(rdev);
> -                       rdev->flags &= ~RADEON_IS_AGP;
> -                       return rv770_init(rdev);
> -               }
>                rv770_suspend(rdev);
>                r600_wb_fini(rdev);
> -               radeon_ib_pool_fini(rdev);
>                radeon_ring_fini(rdev);
>                rv770_pcie_gart_fini(rdev);
>                rdev->accel_working = false;
> @@ -999,10 +985,8 @@ void rv770_fini(struct radeon_device *rdev)
>        radeon_gem_fini(rdev);
>        radeon_fence_driver_fini(rdev);
>        radeon_clocks_fini(rdev);
> -#if __OS_HAS_AGP
>        if (rdev->flags & RADEON_IS_AGP)
>                radeon_agp_fini(rdev);
> -#endif
>        radeon_object_fini(rdev);
>        radeon_atombios_fini(rdev);
>        kfree(rdev->bios);
> --
> 1.6.4.4
>
>
> ------------------------------------------------------------------------------
> Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
> is the only developer event you need to attend this year. Jumpstart your
> developing skills, take BlackBerry mobile applications to market and stay
> ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
> http://p.sf.net/sfu/devconf
> --
> _______________________________________________
> Dri-devel mailing list
> Dri-devel@xxxxxxxxxxxxxxxxxxxxx
> https://lists.sourceforge.net/lists/listinfo/dri-devel
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/