aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/radeon_cp.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2008-05-27 23:28:59 -0400
committerDave Airlie <airlied@redhat.com>2008-06-18 21:27:39 -0400
commit45e519052e8f583a709edd442a23f59581d3fe42 (patch)
treee928f17fdc5f8c52d33a649c361aa5c2cdee720c /drivers/char/drm/radeon_cp.c
parent2735977b12cb0f113aae24afff04747b6d0f5bf1 (diff)
drm/radeon: merge IGP chip setup and fixup RS400 vs RS480 support
We only support RS480 (AMD based IGP) at the moment not RS400 (Intel based IGP) ones. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/char/drm/radeon_cp.c')
-rw-r--r--drivers/char/drm/radeon_cp.c169
1 files changed, 70 insertions, 99 deletions
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 38eda336a657..3a424986e85e 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -2,6 +2,7 @@
2/* 2/*
3 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. 3 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California. 4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * Copyright 2007 Advanced Micro Devices, Inc.
5 * All Rights Reserved. 6 * All Rights Reserved.
6 * 7 *
7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * Permission is hereby granted, free of charge, to any person obtaining a
@@ -40,7 +41,7 @@
40 41
41static int radeon_do_cleanup_cp(struct drm_device * dev); 42static int radeon_do_cleanup_cp(struct drm_device * dev);
42 43
43static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) 44static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
44{ 45{
45 u32 ret; 46 u32 ret;
46 RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff)); 47 RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff));
@@ -49,21 +50,41 @@ static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
49 return ret; 50 return ret;
50} 51}
51 52
53static u32 RS480_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
54{
55 u32 ret;
56 RADEON_WRITE(RS480_NB_MC_INDEX, addr & 0xff);
57 ret = RADEON_READ(RS480_NB_MC_DATA);
58 RADEON_WRITE(RS480_NB_MC_INDEX, 0xff);
59 return ret;
60}
61
52static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) 62static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
53{ 63{
64 u32 ret;
54 RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK)); 65 RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
55 return RADEON_READ(RS690_MC_DATA); 66 ret = RADEON_READ(RS690_MC_DATA);
67 RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_MASK);
68 return ret;
69}
70
71static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
72{
73 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
74 return RS690_READ_MCIND(dev_priv, addr);
75 else
76 return RS480_READ_MCIND(dev_priv, addr);
56} 77}
57 78
58u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) 79u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
59{ 80{
60 81
61 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) 82 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
62 return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); 83 return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
63 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) 84 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
64 return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); 85 return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
65 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) 86 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
66 return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); 87 return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
67 else 88 else
68 return RADEON_READ(RADEON_MC_FB_LOCATION); 89 return RADEON_READ(RADEON_MC_FB_LOCATION);
69} 90}
@@ -71,11 +92,11 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
71static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) 92static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
72{ 93{
73 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) 94 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
74 RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); 95 R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
75 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) 96 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
76 RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); 97 RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
77 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) 98 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
78 RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); 99 R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
79 else 100 else
80 RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); 101 RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
81} 102}
@@ -83,11 +104,11 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
83static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) 104static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
84{ 105{
85 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) 106 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
86 RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); 107 R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
87 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) 108 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
88 RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); 109 RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
89 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) 110 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
90 RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); 111 R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
91 else 112 else
92 RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); 113 RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
93} 114}
@@ -106,15 +127,6 @@ static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
106 return RADEON_READ(RADEON_PCIE_DATA); 127 return RADEON_READ(RADEON_PCIE_DATA);
107} 128}
108 129
109static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr)
110{
111 u32 ret;
112 RADEON_WRITE(RS400_NB_MC_INDEX, addr & 0x7f);
113 ret = RADEON_READ(RS400_NB_MC_DATA);
114 RADEON_WRITE(RS400_NB_MC_INDEX, 0x7f);
115 return ret;
116}
117
118#if RADEON_FIFO_DEBUG 130#if RADEON_FIFO_DEBUG
119static void radeon_status(drm_radeon_private_t * dev_priv) 131static void radeon_status(drm_radeon_private_t * dev_priv)
120{ 132{
@@ -255,7 +267,7 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
255 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || 267 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) ||
256 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || 268 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) ||
257 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || 269 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) ||
258 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400)) { 270 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
259 DRM_INFO("Loading R300 Microcode\n"); 271 DRM_INFO("Loading R300 Microcode\n");
260 for (i = 0; i < 256; i++) { 272 for (i = 0; i < 256; i++) {
261 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, 273 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
@@ -604,114 +616,77 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
604/* Enable or disable IGP GART on the chip */ 616/* Enable or disable IGP GART on the chip */
605static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) 617static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
606{ 618{
607 u32 temp, tmp;
608
609 tmp = RADEON_READ(RADEON_AIC_CNTL);
610 if (on) {
611 DRM_DEBUG("programming igpgart %08X %08lX %08X\n",
612 dev_priv->gart_vm_start,
613 (long)dev_priv->gart_info.bus_addr,
614 dev_priv->gart_size);
615
616 RADEON_WRITE_IGPGART(RS400_MC_MISC_CNTL, RS400_GART_INDEX_REG_EN);
617 RADEON_WRITE_IGPGART(RS400_AGP_ADDRESS_SPACE_SIZE, (RS400_GART_EN |
618 RS400_VA_SIZE_32MB));
619 RADEON_WRITE_IGPGART(RS400_GART_FEATURE_ID, (RS400_HANG_EN |
620 RS400_TLB_ENABLE |
621 RS400_GTW_LAC_EN |
622 RS400_1LEVEL_GART));
623 RADEON_WRITE_IGPGART(RS400_GART_BASE,
624 dev_priv->gart_info.bus_addr);
625
626 temp = RADEON_READ_IGPGART(dev_priv, RS400_AGP_MODE_CNTL);
627 RADEON_WRITE_IGPGART(RS400_AGP_MODE_CNTL, temp);
628
629 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
630 dev_priv->gart_size = 32*1024*1024;
631 radeon_write_agp_location(dev_priv,
632 (((dev_priv->gart_vm_start - 1 +
633 dev_priv->gart_size) & 0xffff0000) |
634 (dev_priv->gart_vm_start >> 16)));
635
636 temp = RADEON_READ_IGPGART(dev_priv, RS400_AGP_ADDRESS_SPACE_SIZE);
637 RADEON_WRITE_IGPGART(RS400_AGP_ADDRESS_SPACE_SIZE, temp);
638
639 RADEON_READ_IGPGART(dev_priv, RS400_GART_CACHE_CNTRL);
640 RADEON_WRITE_IGPGART(RS400_GART_CACHE_CNTRL, RS400_GART_CACHE_INVALIDATE);
641 RADEON_READ_IGPGART(dev_priv, RS400_GART_CACHE_CNTRL);
642 RADEON_WRITE_IGPGART(RS400_GART_CACHE_CNTRL, 0);
643 }
644}
645
646/* Enable or disable RS690 GART on the chip */
647static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on)
648{
649 u32 temp; 619 u32 temp;
650 620
651 if (on) { 621 if (on) {
652 DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n", 622 DRM_DEBUG("programming igp gart %08X %08lX %08X\n",
653 dev_priv->gart_vm_start, 623 dev_priv->gart_vm_start,
654 (long)dev_priv->gart_info.bus_addr, 624 (long)dev_priv->gart_info.bus_addr,
655 dev_priv->gart_size); 625 dev_priv->gart_size);
656 626
657 temp = RS690_READ_MCIND(dev_priv, RS400_MC_MISC_CNTL); 627 temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL);
658 RS690_WRITE_MCIND(RS400_MC_MISC_CNTL, (RS400_GART_INDEX_REG_EN | 628 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
659 RS690_BLOCK_GFX_D3_EN)); 629 IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN |
630 RS690_BLOCK_GFX_D3_EN));
631 else
632 IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN);
660 633
661 RS690_WRITE_MCIND(RS400_AGP_ADDRESS_SPACE_SIZE, (RS400_GART_EN | 634 IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
662 RS400_VA_SIZE_32MB)); 635 RS480_VA_SIZE_32MB));
663 636
664 temp = RS690_READ_MCIND(dev_priv, RS400_GART_FEATURE_ID); 637 temp = IGP_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID);
665 RS690_WRITE_MCIND(RS400_GART_FEATURE_ID, (RS400_HANG_EN | 638 IGP_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN |
666 RS400_TLB_ENABLE | 639 RS480_TLB_ENABLE |
667 RS400_GTW_LAC_EN | 640 RS480_GTW_LAC_EN |
668 RS400_1LEVEL_GART)); 641 RS480_1LEVEL_GART));
669 642
670 temp = dev_priv->gart_info.bus_addr & 0xfffff000; 643 temp = dev_priv->gart_info.bus_addr & 0xfffff000;
671 temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4; 644 temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4;
672 RS690_WRITE_MCIND(RS400_GART_BASE, temp); 645 IGP_WRITE_MCIND(RS480_GART_BASE, temp);
673 646
674 temp = RS690_READ_MCIND(dev_priv, RS400_AGP_MODE_CNTL); 647 temp = IGP_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL);
675 RS690_WRITE_MCIND(RS400_AGP_MODE_CNTL, ((1 << RS400_REQ_TYPE_SNOOP_SHIFT) | 648 IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) |
676 RS400_REQ_TYPE_SNOOP_DIS)); 649 RS480_REQ_TYPE_SNOOP_DIS));
677 650
678 RS690_WRITE_MCIND(RS690_MC_AGP_BASE, 651 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
679 (unsigned int)dev_priv->gart_vm_start); 652 IGP_WRITE_MCIND(RS690_MC_AGP_BASE,
680 653 (unsigned int)dev_priv->gart_vm_start);
681 RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, 0); 654 IGP_WRITE_MCIND(RS690_MC_AGP_BASE_2, 0);
655 } else {
656 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
657 RADEON_WRITE(RS480_AGP_BASE_2, 0);
658 }
682 659
683 dev_priv->gart_size = 32*1024*1024; 660 dev_priv->gart_size = 32*1024*1024;
684 temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & 661 temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
685 0xffff0000) | (dev_priv->gart_vm_start >> 16)); 662 0xffff0000) | (dev_priv->gart_vm_start >> 16));
686 663
687 RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp); 664 radeon_write_agp_location(dev_priv, temp);
688 665
689 temp = RS690_READ_MCIND(dev_priv, RS400_AGP_ADDRESS_SPACE_SIZE); 666 temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE);
690 RS690_WRITE_MCIND(RS400_AGP_ADDRESS_SPACE_SIZE, (RS400_GART_EN | 667 IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
691 RS400_VA_SIZE_32MB)); 668 RS480_VA_SIZE_32MB));
692 669
693 do { 670 do {
694 temp = RS690_READ_MCIND(dev_priv, RS400_GART_CACHE_CNTRL); 671 temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
695 if ((temp & RS690_MC_GART_CLEAR_STATUS) == 672 if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
696 RS690_MC_GART_CLEAR_DONE)
697 break; 673 break;
698 DRM_UDELAY(1); 674 DRM_UDELAY(1);
699 } while (1); 675 } while (1);
700 676
701 RS690_WRITE_MCIND(RS400_GART_CACHE_CNTRL, 677 IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL,
702 RS400_GART_CACHE_INVALIDATE); 678 RS480_GART_CACHE_INVALIDATE);
703 679
704 do { 680 do {
705 temp = RS690_READ_MCIND(dev_priv, RS400_GART_CACHE_CNTRL); 681 temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
706 if ((temp & RS690_MC_GART_CLEAR_STATUS) == 682 if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
707 RS690_MC_GART_CLEAR_DONE)
708 break; 683 break;
709 DRM_UDELAY(1); 684 DRM_UDELAY(1);
710 } while (1); 685 } while (1);
711 686
712 RS690_WRITE_MCIND(RS400_GART_CACHE_CNTRL, 0); 687 IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0);
713 } else { 688 } else {
714 RS690_WRITE_MCIND(RS400_AGP_ADDRESS_SPACE_SIZE, 0); 689 IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0);
715 } 690 }
716} 691}
717 692
@@ -749,12 +724,8 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
749{ 724{
750 u32 tmp; 725 u32 tmp;
751 726
752 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { 727 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
753 radeon_set_rs690gart(dev_priv, on); 728 (dev_priv->flags & RADEON_IS_IGPGART)) {
754 return;
755 }
756
757 if (dev_priv->flags & RADEON_IS_IGPGART) {
758 radeon_set_igpgart(dev_priv, on); 729 radeon_set_igpgart(dev_priv, on);
759 return; 730 return;
760 } 731 }